Linux bluetooth development
 help / color / mirror / Atom feed
* [PATCH 2/2] gitignore: Add tools/avdtp-tester
From: Szymon Janc @ 2013-11-28 11:10 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1385637056-561-1-git-send-email-szymon.janc@tieto.com>

---
 .gitignore | 1 +
 1 file changed, 1 insertion(+)

diff --git a/.gitignore b/.gitignore
index d567d26..2d3435a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -100,6 +100,7 @@ unit/test-gobex-apparam
 unit/test-gobex-header
 unit/test-gobex-packet
 unit/test-gobex-transfer
+unit/test-avdtp
 unit/test-*.log
 unit/test-*.trs
 
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH 1/2] build: Fix build error if path contains spaces
From: Szymon Janc @ 2013-11-28 11:10 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

janccszy@box:~/bluez test$ make
  GEN      lib/bluetooth/bluetooth.h
ln: target ‘lib/bluetooth/bluetooth.h’ is not a directory
make: *** [lib/bluetooth/bluetooth.h] Error 1
---
 Makefile.am | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Makefile.am b/Makefile.am
index 2bb2eb5..a3924aa 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -328,7 +328,7 @@ $(lib_libbluetooth_la_OBJECTS): $(local_headers)
 
 lib/bluetooth/%.h: lib/%.h
 	$(AM_V_at)$(MKDIR_P) lib/bluetooth
-	$(AM_V_GEN)$(LN_S) -f $(abs_top_builddir)/$< $@
+	$(AM_V_GEN)$(LN_S) -f "$(abs_top_builddir)"/$< $@
 
 clean-local:
 	$(RM) -r lib/bluetooth
-- 
1.8.3.2


^ permalink raw reply related

* Re: [PATCH] android/pics: Add PTS PICS for OPP
From: Johan Hedberg @ 2013-11-28  9:45 UTC (permalink / raw)
  To: Jakub Tyszkowski; +Cc: linux-bluetooth
In-Reply-To: <1385625873-8603-1-git-send-email-jakub.tyszkowski@tieto.com>

Hi Jakub,

On Thu, Nov 28, 2013, Jakub Tyszkowski wrote:
> PTS PICS for OPP, targeting Android 4.4.
> 
> ---
>  android/Makefile.am  |   3 +-
>  android/pics-opp.txt | 184 +++++++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 186 insertions(+), 1 deletion(-)
>  create mode 100644 android/pics-opp.txt

Applied. Thanks.

Johan

^ permalink raw reply

* [PATCH v2 6/6] android: Make HAL logging wrapper print to stderr instead of stdout
From: Grzegorz Kolodziejczyk @ 2013-11-28  9:42 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1385631770-3858-1-git-send-email-grzegorz.kolodziejczyk@tieto.com>

From: Szymon Janc <szymon.janc@tieto.com>

This is used for testing and for user it makes no difference. This
will allow to switch on/off verbose logging from automated android
tester.
---
 android/hal-log.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/android/hal-log.h b/android/hal-log.h
index 9bd024d..63ff61b 100644
--- a/android/hal-log.h
+++ b/android/hal-log.h
@@ -25,7 +25,7 @@
 #define LOG_WARN " W"
 #define LOG_ERROR " E"
 #define LOG_DEBUG " D"
-#define ALOG(pri, tag, fmt, arg...) printf(tag pri": " fmt"\n", ##arg)
+#define ALOG(pri, tag, fmt, arg...) fprintf(stderr, tag pri": " fmt"\n", ##arg)
 #endif
 
 #define info(fmt, arg...) ALOG(LOG_INFO, LOG_TAG, fmt, ##arg)
-- 
1.8.4.2


^ permalink raw reply related

* [PATCH v2 5/6] android: Add basic test and handle mgmt notifications, hal cb
From: Grzegorz Kolodziejczyk @ 2013-11-28  9:42 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1385631770-3858-1-git-send-email-grzegorz.kolodziejczyk@tieto.com>

This adds basic enable test case. Mgmt notifications and HAL callbacks
are now handled.
---
 android/android-tester.c | 230 +++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 224 insertions(+), 6 deletions(-)

diff --git a/android/android-tester.c b/android/android-tester.c
index 5e5afe0..5c24dc4 100644
--- a/android/android-tester.c
+++ b/android/android-tester.c
@@ -40,16 +40,126 @@
 static pthread_cond_t emulator_cond = PTHREAD_COND_INITIALIZER;
 static pthread_mutex_t emulator_mutex = PTHREAD_MUTEX_INITIALIZER;
 
+/*
+ * those are assigned to HAL methods and callbacks, we use ID later
+ * on mapped in switch-case due to different functions prototypes.
+ */
+
+enum hal_bluetooth_callbacks_id {
+	adapter_test_end,
+	adapter_state_changed_on,
+	adapter_state_changed_off,
+	adapter_prop_bdaddr,
+	adapter_prop_bdname,
+	adapter_prop_uuids,
+	adapter_prop_cod,
+	adapter_prop_scan_mode,
+	adapter_prop_disc_timeout,
+	adapter_prop_service_record,
+	adapter_prop_bonded_devices
+};
+
+struct generic_data {
+	uint32_t expect_settings_set;
+	uint8_t expected_hal_callbacks[];
+};
+
 struct test_data {
 	struct mgmt *mgmt;
 	uint16_t mgmt_index;
+	unsigned int mgmt_settings_id;
 	struct hciemu *hciemu;
 	enum hciemu_type hciemu_type;
-	void *test_data;
+	const struct generic_data *test_data;
 	pthread_t emulator_thread;
 	const bt_interface_t *if_bluetooth;
+
+	bool mgmt_settings_set;
+	bool hal_cb_called;
+
+	GSList *expected_callbacks;
 };
 
+static void test_update_state(void)
+{
+	struct test_data *data = tester_get_data();
+
+	if (data->mgmt_settings_set && data->hal_cb_called)
+		tester_test_passed();
+}
+
+static void test_mgmt_settings_set(struct test_data *data)
+{
+	data->mgmt_settings_set = true;
+
+	test_update_state();
+}
+
+static void command_generic_new_settings(uint16_t index, uint16_t length,
+					const void *param, void *user_data)
+{
+	struct test_data *data = tester_get_data();
+	uint32_t settings;
+
+	if (length != 4) {
+		tester_warn("Invalid parameter size for new settings event");
+		tester_test_failed();
+		return;
+	}
+
+	settings = bt_get_le32(param);
+
+	if ((settings & data->test_data->expect_settings_set) !=
+					data->test_data->expect_settings_set)
+		return;
+
+	test_mgmt_settings_set(data);
+	mgmt_unregister(data->mgmt, data->mgmt_settings_id);
+}
+
+static void hal_cb_init(void)
+{
+	struct test_data *data = tester_get_data();
+	unsigned int i = 0;
+
+	while (data->test_data->expected_hal_callbacks[i]) {
+						data->expected_callbacks =
+				g_slist_append(data->expected_callbacks,
+		GINT_TO_POINTER(data->test_data->expected_hal_callbacks[i]));
+		i++;
+	}
+}
+
+static void mgmt_cb_init(struct test_data *data)
+{
+	if (!data->test_data->expect_settings_set)
+		test_mgmt_settings_set(data);
+	else
+		data->mgmt_settings_id = mgmt_register(data->mgmt,
+					MGMT_EV_NEW_SETTINGS, data->mgmt_index,
+				command_generic_new_settings, NULL, NULL);
+}
+
+static int get_expected_hal_cb(void)
+{
+	struct test_data *data = tester_get_data();
+
+	return GPOINTER_TO_INT(data->expected_callbacks->data);
+}
+
+static void remove_expected_hal_cb(void)
+{
+	struct test_data *data = tester_get_data();
+
+	data->expected_callbacks = g_slist_remove(data->expected_callbacks,
+						data->expected_callbacks->data);
+
+	if (!data->expected_callbacks)
+		data->hal_cb_called = true;
+
+	test_update_state();
+}
+
 static void read_info_callback(uint8_t status, uint16_t length,
 					const void *param, void *user_data)
 {
@@ -257,10 +367,109 @@ static void *emulator(void *user_data)
 	return NULL;
 }
 
+static void adapter_state_changed_cb(bt_state_t state)
+{
+	switch (get_expected_hal_cb()) {
+	case adapter_state_changed_on:
+		if (state == BT_STATE_ON)
+			remove_expected_hal_cb();
+		else
+			tester_test_failed();
+		break;
+	default:
+		break;
+	}
+}
+
+static void adapter_properties_cb(bt_status_t status, int num_properties,
+						bt_property_t *properties)
+{
+	enum hal_bluetooth_callbacks_id hal_cb;
+	int i;
+
+	for (i = 0; i < num_properties; i++) {
+		hal_cb = get_expected_hal_cb();
+		switch (properties[i].type) {
+		case BT_PROPERTY_BDADDR:
+			if (hal_cb != adapter_prop_bdaddr) {
+				tester_test_failed();
+				return;
+			}
+			remove_expected_hal_cb();
+			break;
+		case BT_PROPERTY_BDNAME:
+			if (hal_cb != adapter_prop_bdname) {
+				tester_test_failed();
+				return;
+			}
+			remove_expected_hal_cb();
+			break;
+		case BT_PROPERTY_UUIDS:
+			if (hal_cb != adapter_prop_uuids) {
+				tester_test_failed();
+				return;
+			}
+			remove_expected_hal_cb();
+			break;
+		case BT_PROPERTY_CLASS_OF_DEVICE:
+			if (hal_cb != adapter_prop_cod) {
+				tester_test_failed();
+				return;
+			}
+			remove_expected_hal_cb();
+			break;
+		case BT_PROPERTY_TYPE_OF_DEVICE:
+			if (hal_cb != adapter_prop_bdaddr) {
+				tester_test_failed();
+				return;
+			}
+			remove_expected_hal_cb();
+			break;
+		case BT_PROPERTY_SERVICE_RECORD:
+			if (hal_cb != adapter_prop_service_record) {
+				tester_test_failed();
+				return;
+			}
+			remove_expected_hal_cb();
+			break;
+		case BT_PROPERTY_ADAPTER_SCAN_MODE:
+			if (hal_cb != adapter_prop_scan_mode) {
+				tester_test_failed();
+				return;
+			}
+			remove_expected_hal_cb();
+			break;
+		case BT_PROPERTY_ADAPTER_BONDED_DEVICES:
+			if (hal_cb != adapter_prop_bonded_devices) {
+				tester_test_failed();
+				return;
+			}
+			remove_expected_hal_cb();
+			break;
+		case BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT:
+			if (hal_cb != adapter_prop_disc_timeout) {
+				tester_test_failed();
+				return;
+			}
+			remove_expected_hal_cb();
+			break;
+		default:
+			break;
+		}
+	}
+}
+
+static const struct generic_data bluetooth_enable_success_test = {
+	.expected_hal_callbacks = {adapter_prop_bdaddr, adapter_prop_bdname,
+			adapter_prop_uuids, adapter_prop_cod,
+			adapter_prop_scan_mode, adapter_prop_disc_timeout,
+			adapter_state_changed_on, adapter_test_end}
+};
+
 static bt_callbacks_t bt_callbacks = {
 	.size = sizeof(bt_callbacks),
-	.adapter_state_changed_cb = NULL,
-	.adapter_properties_cb = NULL,
+	.adapter_state_changed_cb = adapter_state_changed_cb,
+	.adapter_properties_cb = adapter_properties_cb,
 	.remote_device_properties_cb = NULL,
 	.device_found_cb = NULL,
 	.discovery_state_changed_cb = NULL,
@@ -343,12 +552,20 @@ static void teardown(const void *test_data)
 		data->emulator_thread = 0;
 	}
 
+	if (data->expected_callbacks)
+		g_slist_free(data->expected_callbacks);
+
 	tester_teardown_complete();
 }
 
-static void pass_test(const void *test_data)
+static void test_enable(const void *test_data)
 {
-	tester_test_passed();
+	struct test_data *data = tester_get_data();
+
+	hal_cb_init();
+	mgmt_cb_init(data);
+
+	data->if_bluetooth->enable();
 }
 
 #define test_bredrle(name, data, test_setup, test, test_teardown) \
@@ -368,7 +585,8 @@ int main(int argc, char *argv[])
 {
 	tester_init(&argc, &argv);
 
-	test_bredrle("test", NULL, setup, pass_test, teardown);
+	test_bredrle("Test Enable - Success", &bluetooth_enable_success_test,
+						setup, test_enable, teardown);
 
 	return tester_run();
 }
-- 
1.8.4.2


^ permalink raw reply related

* [PATCH v2 4/6] android: Add stack initialization of stack in setup
From: Grzegorz Kolodziejczyk @ 2013-11-28  9:42 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Marcin Kraglak
In-Reply-To: <1385631770-3858-1-git-send-email-grzegorz.kolodziejczyk@tieto.com>

From: Marcin Kraglak <marcin.kraglak@tieto.com>

This add stack initialization and cleanup in setup/teardown.
---
 android/Makefile.am      |  8 ++++--
 android/android-tester.c | 69 +++++++++++++++++++++++++++++++++++++++++++++---
 2 files changed, 71 insertions(+), 6 deletions(-)

diff --git a/android/Makefile.am b/android/Makefile.am
index b19ab4e..e71857e 100644
--- a/android/Makefile.am
+++ b/android/Makefile.am
@@ -90,9 +90,13 @@ android_android_tester_SOURCES = emulator/btdev.h emulator/btdev.c \
 				src/shared/mgmt.h src/shared/mgmt.c \
 				src/shared/hciemu.h src/shared/hciemu.c \
 				src/shared/tester.h src/shared/tester.c \
-				android/android-tester.c
+				android/hal-utils.h android/hal-utils.c \
+				android/client/hwmodule.c android/android-tester.c
 
-android_android_tester_LDADD = lib/libbluetooth-internal.la @GLIB_LIBS@
+android_android_tester_CFLAGS = $(AM_CFLAGS) -I$(srcdir)/android
+
+android_android_tester_LDADD = lib/libbluetooth-internal.la \
+				android/libhal-internal.la @GLIB_LIBS@
 
 android_android_tester_LDFLAGS = -pthread
 
diff --git a/android/android-tester.c b/android/android-tester.c
index 16e8ec0..5e5afe0 100644
--- a/android/android-tester.c
+++ b/android/android-tester.c
@@ -32,6 +32,9 @@
 #include "src/shared/mgmt.h"
 #include "src/shared/hciemu.h"
 
+#include <hardware/hardware.h>
+#include <hardware/bluetooth.h>
+
 #define WAIT_FOR_CONDITION_TIME 2 /* in seconds */
 
 static pthread_cond_t emulator_cond = PTHREAD_COND_INITIALIZER;
@@ -44,6 +47,7 @@ struct test_data {
 	enum hciemu_type hciemu_type;
 	void *test_data;
 	pthread_t emulator_thread;
+	const bt_interface_t *if_bluetooth;
 };
 
 static void read_info_callback(uint8_t status, uint16_t length,
@@ -253,10 +257,30 @@ static void *emulator(void *user_data)
 	return NULL;
 }
 
+static bt_callbacks_t bt_callbacks = {
+	.size = sizeof(bt_callbacks),
+	.adapter_state_changed_cb = NULL,
+	.adapter_properties_cb = NULL,
+	.remote_device_properties_cb = NULL,
+	.device_found_cb = NULL,
+	.discovery_state_changed_cb = NULL,
+	.pin_request_cb = NULL,
+	.ssp_request_cb = NULL,
+	.bond_state_changed_cb = NULL,
+	.acl_state_changed_cb = NULL,
+	.thread_evt_cb = NULL,
+	.dut_mode_recv_cb = NULL,
+	.le_test_mode_cb = NULL
+};
+
 static void setup(const void *test_data)
 {
 	struct test_data *data = tester_get_data();
+	const hw_module_t *module;
+	hw_device_t *device;
+	bt_status_t status;
 	struct timespec ts;
+	int err;
 
 	clock_gettime(CLOCK_REALTIME, &ts);
 	ts.tv_sec += WAIT_FOR_CONDITION_TIME;
@@ -269,19 +293,56 @@ static void setup(const void *test_data)
 	}
 
 	if (pthread_cond_timedwait(&emulator_cond, &emulator_mutex,
-								&ts))
+								&ts)) {
 		tester_setup_failed();
-	else
-		tester_setup_complete();
+		pthread_mutex_unlock(&emulator_mutex);
+		return;
+	}
 
 	pthread_mutex_unlock(&emulator_mutex);
+
+	err = hw_get_module(BT_HARDWARE_MODULE_ID, &module);
+	if (err) {
+		tester_setup_failed();
+		return;
+	}
+
+	err = module->methods->open(module, BT_HARDWARE_MODULE_ID, &device);
+	if (err) {
+		tester_setup_failed();
+		return;
+	}
+
+	data->if_bluetooth = ((bluetooth_device_t *)
+					device)->get_bluetooth_interface();
+	if (!data->if_bluetooth) {
+		tester_setup_failed();
+		return;
+	}
+
+	status = data->if_bluetooth->init(&bt_callbacks);
+	if (status != BT_STATUS_SUCCESS) {
+		data->if_bluetooth = NULL;
+		tester_setup_failed();
+	}
+
+	tester_setup_complete();
 }
 
 static void teardown(const void *test_data)
 {
 	struct test_data *data = tester_get_data();
 
-	pthread_join(data->emulator_thread, NULL);
+	if (data->if_bluetooth) {
+		data->if_bluetooth->cleanup();
+		data->if_bluetooth = NULL;
+	}
+
+	if (data->emulator_thread) {
+		pthread_join(data->emulator_thread, NULL);
+		data->emulator_thread = 0;
+	}
+
 	tester_teardown_complete();
 }
 
-- 
1.8.4.2


^ permalink raw reply related

* [PATCH v2 3/6] android: Start emulator in separate thread
From: Grzegorz Kolodziejczyk @ 2013-11-28  9:42 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Marcin Kraglak
In-Reply-To: <1385631770-3858-1-git-send-email-grzegorz.kolodziejczyk@tieto.com>

From: Marcin Kraglak <marcin.kraglak@tieto.com>

This is needed because bluetooth->init call is blocking,
and we have to emulate normal behaviour of android environment.
That thread will exit if it won't receive any message in 2 sec
or when bluetoothd will exit. It will be joined in teardown.
---
 android/Makefile.am      |   2 +
 android/android-tester.c | 125 ++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 126 insertions(+), 1 deletion(-)

diff --git a/android/Makefile.am b/android/Makefile.am
index 905032d..b19ab4e 100644
--- a/android/Makefile.am
+++ b/android/Makefile.am
@@ -94,6 +94,8 @@ android_android_tester_SOURCES = emulator/btdev.h emulator/btdev.c \
 
 android_android_tester_LDADD = lib/libbluetooth-internal.la @GLIB_LIBS@
 
+android_android_tester_LDFLAGS = -pthread
+
 endif
 
 EXTRA_DIST += android/Android.mk android/hal-ipc-api.txt android/README \
diff --git a/android/android-tester.c b/android/android-tester.c
index 48e408d..16e8ec0 100644
--- a/android/android-tester.c
+++ b/android/android-tester.c
@@ -15,9 +15,15 @@
  *
  */
 
+#include <stdlib.h>
 #include <unistd.h>
 
 #include <glib.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/un.h>
+#include <pthread.h>
 
 #include "lib/bluetooth.h"
 #include "lib/mgmt.h"
@@ -26,12 +32,18 @@
 #include "src/shared/mgmt.h"
 #include "src/shared/hciemu.h"
 
+#define WAIT_FOR_CONDITION_TIME 2 /* in seconds */
+
+static pthread_cond_t emulator_cond = PTHREAD_COND_INITIALIZER;
+static pthread_mutex_t emulator_mutex = PTHREAD_MUTEX_INITIALIZER;
+
 struct test_data {
 	struct mgmt *mgmt;
 	uint16_t mgmt_index;
 	struct hciemu *hciemu;
 	enum hciemu_type hciemu_type;
 	void *test_data;
+	pthread_t emulator_thread;
 };
 
 static void read_info_callback(uint8_t status, uint16_t length,
@@ -162,6 +174,117 @@ static void test_post_teardown(const void *test_data)
 	data->hciemu = NULL;
 }
 
+static void bluetoothd_start(void)
+{
+	struct test_data *data = tester_get_data();
+	char prg_name[PATH_MAX + 1];
+	char index[8];
+	char *prg_argv[4];
+	pid_t pid;
+	int status;
+
+	snprintf(prg_name, sizeof(prg_name), "%s/%s", "android", "bluetoothd");
+	snprintf(index, sizeof(index), "%d", data->mgmt_index);
+
+	prg_argv[0] = prg_name;
+	prg_argv[1] = "-i";
+	prg_argv[2] = index;
+	prg_argv[3] = NULL;
+
+	pid = fork();
+	if (pid < 0) {
+		perror("Failed to fork new process");
+		return;
+	}
+
+	if (pid == 0) {
+		if (!tester_use_debug())
+			fclose(stderr);
+
+		execve(prg_argv[0], prg_argv, NULL);
+		exit(0);
+	}
+
+	pid = waitpid(-1, &status, 0);
+}
+
+static void *emulator(void *user_data)
+{
+	static const char SYSTEM_SOCKET_PATH[] = "\0android_system";
+	char buf[4096];
+	struct sockaddr_un addr;
+	struct timeval tv;
+	int fd;
+	ssize_t len;
+
+	fd = socket(PF_LOCAL, SOCK_DGRAM | SOCK_CLOEXEC, 0);
+	if (fd < 0)
+		return NULL;
+
+	tv.tv_sec = WAIT_FOR_CONDITION_TIME;
+	tv.tv_usec = 0;
+	setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(tv));
+
+	memset(&addr, 0, sizeof(addr));
+	addr.sun_family = AF_UNIX;
+	memcpy(addr.sun_path, SYSTEM_SOCKET_PATH, sizeof(SYSTEM_SOCKET_PATH));
+
+	if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
+		perror("Failed to bind system socket");
+		close(fd);
+		pthread_exit(NULL);
+		return NULL;
+	}
+
+	pthread_mutex_lock(&emulator_mutex);
+	pthread_cond_signal(&emulator_cond);
+	pthread_mutex_unlock(&emulator_mutex);
+
+	len = read(fd, buf, sizeof(buf));
+	if (len <= 0 || (strcmp(buf, "ctl.start=bluetoothd"))) {
+		close(fd);
+		pthread_exit(NULL);
+		return NULL;
+	}
+
+	close(fd);
+	bluetoothd_start();
+	pthread_exit(NULL);
+	return NULL;
+}
+
+static void setup(const void *test_data)
+{
+	struct test_data *data = tester_get_data();
+	struct timespec ts;
+
+	clock_gettime(CLOCK_REALTIME, &ts);
+	ts.tv_sec += WAIT_FOR_CONDITION_TIME;
+
+	pthread_mutex_lock(&emulator_mutex);
+
+	if (pthread_create(&data->emulator_thread, NULL, emulator, NULL)) {
+		tester_setup_failed();
+		return;
+	}
+
+	if (pthread_cond_timedwait(&emulator_cond, &emulator_mutex,
+								&ts))
+		tester_setup_failed();
+	else
+		tester_setup_complete();
+
+	pthread_mutex_unlock(&emulator_mutex);
+}
+
+static void teardown(const void *test_data)
+{
+	struct test_data *data = tester_get_data();
+
+	pthread_join(data->emulator_thread, NULL);
+	tester_teardown_complete();
+}
+
 static void pass_test(const void *test_data)
 {
 	tester_test_passed();
@@ -184,7 +307,7 @@ int main(int argc, char *argv[])
 {
 	tester_init(&argc, &argv);
 
-	test_bredrle("test", NULL, NULL, pass_test, NULL);
+	test_bredrle("test", NULL, setup, pass_test, teardown);
 
 	return tester_run();
 }
-- 
1.8.4.2


^ permalink raw reply related

* [PATCH v2 2/6] android: Add pre-setup and post-teardown routines
From: Grzegorz Kolodziejczyk @ 2013-11-28  9:42 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Marcin Kraglak
In-Reply-To: <1385631770-3858-1-git-send-email-grzegorz.kolodziejczyk@tieto.com>

From: Marcin Kraglak <marcin.kraglak@tieto.com>

This will add hciemu initialization and cleanup. These functions
will be called to create hci emulator and cleanup it.
---
 android/Makefile.am      |  10 ++-
 android/android-tester.c | 171 ++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 179 insertions(+), 2 deletions(-)

diff --git a/android/Makefile.am b/android/Makefile.am
index 9390422..905032d 100644
--- a/android/Makefile.am
+++ b/android/Makefile.am
@@ -84,7 +84,15 @@ android_haltest_LDFLAGS = -pthread
 
 noinst_PROGRAMS += android/android-tester
 
-android_android_tester_SOURCES = android/android-tester.c
+android_android_tester_SOURCES = emulator/btdev.h emulator/btdev.c \
+				emulator/bthost.h emulator/bthost.c \
+				src/shared/util.h src/shared/util.c \
+				src/shared/mgmt.h src/shared/mgmt.c \
+				src/shared/hciemu.h src/shared/hciemu.c \
+				src/shared/tester.h src/shared/tester.c \
+				android/android-tester.c
+
+android_android_tester_LDADD = lib/libbluetooth-internal.la @GLIB_LIBS@
 
 endif
 
diff --git a/android/android-tester.c b/android/android-tester.c
index f5c42b0..48e408d 100644
--- a/android/android-tester.c
+++ b/android/android-tester.c
@@ -15,7 +15,176 @@
  *
  */
 
+#include <unistd.h>
+
+#include <glib.h>
+
+#include "lib/bluetooth.h"
+#include "lib/mgmt.h"
+
+#include "src/shared/tester.h"
+#include "src/shared/mgmt.h"
+#include "src/shared/hciemu.h"
+
+struct test_data {
+	struct mgmt *mgmt;
+	uint16_t mgmt_index;
+	struct hciemu *hciemu;
+	enum hciemu_type hciemu_type;
+	void *test_data;
+};
+
+static void read_info_callback(uint8_t status, uint16_t length,
+					const void *param, void *user_data)
+{
+	struct test_data *data = tester_get_data();
+	const struct mgmt_rp_read_info *rp = param;
+	char addr[18];
+	uint16_t manufacturer;
+	uint32_t supported_settings, current_settings;
+
+	tester_print("Read Info callback");
+	tester_print("  Status: 0x%02x", status);
+
+	if (status || !param) {
+		tester_pre_setup_failed();
+		return;
+	}
+
+	ba2str(&rp->bdaddr, addr);
+	manufacturer = btohs(rp->manufacturer);
+	supported_settings = btohl(rp->supported_settings);
+	current_settings = btohl(rp->current_settings);
+
+	tester_print("  Address: %s", addr);
+	tester_print("  Version: 0x%02x", rp->version);
+	tester_print("  Manufacturer: 0x%04x", manufacturer);
+	tester_print("  Supported settings: 0x%08x", supported_settings);
+	tester_print("  Current settings: 0x%08x", current_settings);
+	tester_print("  Class: 0x%02x%02x%02x",
+			rp->dev_class[2], rp->dev_class[1], rp->dev_class[0]);
+	tester_print("  Name: %s", rp->name);
+	tester_print("  Short name: %s", rp->short_name);
+
+	if (strcmp(hciemu_get_address(data->hciemu), addr)) {
+		tester_pre_setup_failed();
+		return;
+	}
+
+	tester_pre_setup_complete();
+}
+
+static void index_added_callback(uint16_t index, uint16_t length,
+					const void *param, void *user_data)
+{
+	struct test_data *data = tester_get_data();
+
+	tester_print("Index Added callback");
+	tester_print("  Index: 0x%04x", index);
+
+	data->mgmt_index = index;
+
+	mgmt_send(data->mgmt, MGMT_OP_READ_INFO, data->mgmt_index, 0, NULL,
+					read_info_callback, NULL, NULL);
+}
+
+static void index_removed_callback(uint16_t index, uint16_t length,
+					const void *param, void *user_data)
+{
+	struct test_data *data = tester_get_data();
+
+	tester_print("Index Removed callback");
+	tester_print("  Index: 0x%04x", index);
+
+	if (index != data->mgmt_index)
+		return;
+
+	mgmt_unregister_index(data->mgmt, data->mgmt_index);
+
+	mgmt_unref(data->mgmt);
+	data->mgmt = NULL;
+
+	tester_post_teardown_complete();
+}
+
+static void read_index_list_callback(uint8_t status, uint16_t length,
+					const void *param, void *user_data)
+{
+	struct test_data *data = tester_get_data();
+
+	tester_print("Read Index List callback");
+	tester_print("  Status: 0x%02x", status);
+
+	if (status || !param) {
+		tester_pre_setup_failed();
+		return;
+	}
+
+	mgmt_register(data->mgmt, MGMT_EV_INDEX_ADDED, MGMT_INDEX_NONE,
+					index_added_callback, NULL, NULL);
+
+	mgmt_register(data->mgmt, MGMT_EV_INDEX_REMOVED, MGMT_INDEX_NONE,
+					index_removed_callback, NULL, NULL);
+
+	data->hciemu = hciemu_new(data->hciemu_type);
+	if (!data->hciemu) {
+		tester_warn("Failed to setup HCI emulation");
+		tester_pre_setup_failed();
+		return;
+	}
+
+	tester_print("New hciemu instance created");
+}
+
+static void test_pre_setup(const void *test_data)
+{
+	struct test_data *data = tester_get_data();
+
+	if (!tester_use_debug())
+		fclose(stderr);
+
+	data->mgmt = mgmt_new_default();
+	if (!data->mgmt) {
+		tester_warn("Failed to setup management interface");
+		tester_pre_setup_failed();
+		return;
+	}
+
+	mgmt_send(data->mgmt, MGMT_OP_READ_INDEX_LIST, MGMT_INDEX_NONE, 0,
+				NULL, read_index_list_callback, NULL, NULL);
+}
+
+static void test_post_teardown(const void *test_data)
+{
+	struct test_data *data = tester_get_data();
+
+	hciemu_unref(data->hciemu);
+	data->hciemu = NULL;
+}
+
+static void pass_test(const void *test_data)
+{
+	tester_test_passed();
+}
+
+#define test_bredrle(name, data, test_setup, test, test_teardown) \
+	do { \
+		struct test_data *user; \
+		user = g_malloc0(sizeof(struct test_data)); \
+		if (!user) \
+			break; \
+		user->hciemu_type = HCIEMU_TYPE_BREDRLE; \
+		user->test_data = data; \
+		tester_add_full(name, data, test_pre_setup, test_setup, \
+				test, test_teardown, test_post_teardown, \
+							3, user, g_free); \
+	} while (0)
+
 int main(int argc, char *argv[])
 {
-	return 0;
+	tester_init(&argc, &argv);
+
+	test_bredrle("test", NULL, NULL, pass_test, NULL);
+
+	return tester_run();
 }
-- 
1.8.4.2


^ permalink raw reply related

* [PATCH v2 1/6] android: Add android-tester
From: Grzegorz Kolodziejczyk @ 2013-11-28  9:42 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Marcin Kraglak
In-Reply-To: <1385631770-3858-1-git-send-email-grzegorz.kolodziejczyk@tieto.com>

From: Marcin Kraglak <marcin.kraglak@tieto.com>

This commit add android-tester.c to tree and Makefile.am.
This will contain set of unit tests for testing android daemon.
---
 android/Makefile.am      |  4 ++++
 android/android-tester.c | 21 +++++++++++++++++++++
 2 files changed, 25 insertions(+)
 create mode 100644 android/android-tester.c

diff --git a/android/Makefile.am b/android/Makefile.am
index 94d231f..9390422 100644
--- a/android/Makefile.am
+++ b/android/Makefile.am
@@ -82,6 +82,10 @@ android_haltest_CFLAGS = $(AM_CFLAGS) -I$(srcdir)/android \
 
 android_haltest_LDFLAGS = -pthread
 
+noinst_PROGRAMS += android/android-tester
+
+android_android_tester_SOURCES = android/android-tester.c
+
 endif
 
 EXTRA_DIST += android/Android.mk android/hal-ipc-api.txt android/README \
diff --git a/android/android-tester.c b/android/android-tester.c
new file mode 100644
index 0000000..f5c42b0
--- /dev/null
+++ b/android/android-tester.c
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ *
+ */
+
+int main(int argc, char *argv[])
+{
+	return 0;
+}
-- 
1.8.4.2


^ permalink raw reply related

* [PATCH v2 0/6] android: initial code for automated tests
From: Grzegorz Kolodziejczyk @ 2013-11-28  9:42 UTC (permalink / raw)
  To: linux-bluetooth

V2:
 - change-id removed
 - bogus patch removed from serie

from V1:

This serie adds initial code for automated android deamon and HAL library
tests. Skeleton and one initial test case is added.

-- 
Best regards,
Grzegorz

Grzegorz Kolodziejczyk (1):
  android: Add basic test and handle mgmt notifications, hal cb

Marcin Kraglak (4):
  android: Add android-tester
  android: Add pre-setup and post-teardown routines
  android: Start emulator in separate thread
  android: Add stack initialization of stack in setup

Szymon Janc (1):
  android: Make HAL logging wrapper print to stderr instead of stdout

 android/Makefile.am      |  18 ++
 android/android-tester.c | 592 +++++++++++++++++++++++++++++++++++++++++++++++
 android/hal-log.h        |   2 +-
 3 files changed, 611 insertions(+), 1 deletion(-)
 create mode 100644 android/android-tester.c

-- 
1.8.4.2


^ permalink raw reply

* [PATCH 6/6] android: Make HAL logging wrapper print to stderr instead of stdout
From: Grzegorz Kolodziejczyk @ 2013-11-28  9:34 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1385631296-2856-1-git-send-email-grzegorz.kolodziejczyk@tieto.com>

From: Szymon Janc <szymon.janc@tieto.com>

This is used for testing and for user it makes no difference. This
will allow to switch on/off verbose logging from automated android
tester.
---
 android/hal-log.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/android/hal-log.h b/android/hal-log.h
index 9bd024d..63ff61b 100644
--- a/android/hal-log.h
+++ b/android/hal-log.h
@@ -25,7 +25,7 @@
 #define LOG_WARN " W"
 #define LOG_ERROR " E"
 #define LOG_DEBUG " D"
-#define ALOG(pri, tag, fmt, arg...) printf(tag pri": " fmt"\n", ##arg)
+#define ALOG(pri, tag, fmt, arg...) fprintf(stderr, tag pri": " fmt"\n", ##arg)
 #endif
 
 #define info(fmt, arg...) ALOG(LOG_INFO, LOG_TAG, fmt, ##arg)
-- 
1.8.4.2


^ permalink raw reply related

* [PATCH 5/6] android: Add basic test and handle mgmt notifications, hal cb
From: Grzegorz Kolodziejczyk @ 2013-11-28  9:34 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1385631296-2856-1-git-send-email-grzegorz.kolodziejczyk@tieto.com>

This adds basic enable test case. Mgmt notifications and HAL callbacks
are now handled.

Change-Id: Icd222df3eb7093b291dbc83e462679f93e8114fc
---
 android/android-tester.c | 230 +++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 224 insertions(+), 6 deletions(-)

diff --git a/android/android-tester.c b/android/android-tester.c
index 5e5afe0..5c24dc4 100644
--- a/android/android-tester.c
+++ b/android/android-tester.c
@@ -40,16 +40,126 @@
 static pthread_cond_t emulator_cond = PTHREAD_COND_INITIALIZER;
 static pthread_mutex_t emulator_mutex = PTHREAD_MUTEX_INITIALIZER;
 
+/*
+ * those are assigned to HAL methods and callbacks, we use ID later
+ * on mapped in switch-case due to different functions prototypes.
+ */
+
+enum hal_bluetooth_callbacks_id {
+	adapter_test_end,
+	adapter_state_changed_on,
+	adapter_state_changed_off,
+	adapter_prop_bdaddr,
+	adapter_prop_bdname,
+	adapter_prop_uuids,
+	adapter_prop_cod,
+	adapter_prop_scan_mode,
+	adapter_prop_disc_timeout,
+	adapter_prop_service_record,
+	adapter_prop_bonded_devices
+};
+
+struct generic_data {
+	uint32_t expect_settings_set;
+	uint8_t expected_hal_callbacks[];
+};
+
 struct test_data {
 	struct mgmt *mgmt;
 	uint16_t mgmt_index;
+	unsigned int mgmt_settings_id;
 	struct hciemu *hciemu;
 	enum hciemu_type hciemu_type;
-	void *test_data;
+	const struct generic_data *test_data;
 	pthread_t emulator_thread;
 	const bt_interface_t *if_bluetooth;
+
+	bool mgmt_settings_set;
+	bool hal_cb_called;
+
+	GSList *expected_callbacks;
 };
 
+static void test_update_state(void)
+{
+	struct test_data *data = tester_get_data();
+
+	if (data->mgmt_settings_set && data->hal_cb_called)
+		tester_test_passed();
+}
+
+static void test_mgmt_settings_set(struct test_data *data)
+{
+	data->mgmt_settings_set = true;
+
+	test_update_state();
+}
+
+static void command_generic_new_settings(uint16_t index, uint16_t length,
+					const void *param, void *user_data)
+{
+	struct test_data *data = tester_get_data();
+	uint32_t settings;
+
+	if (length != 4) {
+		tester_warn("Invalid parameter size for new settings event");
+		tester_test_failed();
+		return;
+	}
+
+	settings = bt_get_le32(param);
+
+	if ((settings & data->test_data->expect_settings_set) !=
+					data->test_data->expect_settings_set)
+		return;
+
+	test_mgmt_settings_set(data);
+	mgmt_unregister(data->mgmt, data->mgmt_settings_id);
+}
+
+static void hal_cb_init(void)
+{
+	struct test_data *data = tester_get_data();
+	unsigned int i = 0;
+
+	while (data->test_data->expected_hal_callbacks[i]) {
+						data->expected_callbacks =
+				g_slist_append(data->expected_callbacks,
+		GINT_TO_POINTER(data->test_data->expected_hal_callbacks[i]));
+		i++;
+	}
+}
+
+static void mgmt_cb_init(struct test_data *data)
+{
+	if (!data->test_data->expect_settings_set)
+		test_mgmt_settings_set(data);
+	else
+		data->mgmt_settings_id = mgmt_register(data->mgmt,
+					MGMT_EV_NEW_SETTINGS, data->mgmt_index,
+				command_generic_new_settings, NULL, NULL);
+}
+
+static int get_expected_hal_cb(void)
+{
+	struct test_data *data = tester_get_data();
+
+	return GPOINTER_TO_INT(data->expected_callbacks->data);
+}
+
+static void remove_expected_hal_cb(void)
+{
+	struct test_data *data = tester_get_data();
+
+	data->expected_callbacks = g_slist_remove(data->expected_callbacks,
+						data->expected_callbacks->data);
+
+	if (!data->expected_callbacks)
+		data->hal_cb_called = true;
+
+	test_update_state();
+}
+
 static void read_info_callback(uint8_t status, uint16_t length,
 					const void *param, void *user_data)
 {
@@ -257,10 +367,109 @@ static void *emulator(void *user_data)
 	return NULL;
 }
 
+static void adapter_state_changed_cb(bt_state_t state)
+{
+	switch (get_expected_hal_cb()) {
+	case adapter_state_changed_on:
+		if (state == BT_STATE_ON)
+			remove_expected_hal_cb();
+		else
+			tester_test_failed();
+		break;
+	default:
+		break;
+	}
+}
+
+static void adapter_properties_cb(bt_status_t status, int num_properties,
+						bt_property_t *properties)
+{
+	enum hal_bluetooth_callbacks_id hal_cb;
+	int i;
+
+	for (i = 0; i < num_properties; i++) {
+		hal_cb = get_expected_hal_cb();
+		switch (properties[i].type) {
+		case BT_PROPERTY_BDADDR:
+			if (hal_cb != adapter_prop_bdaddr) {
+				tester_test_failed();
+				return;
+			}
+			remove_expected_hal_cb();
+			break;
+		case BT_PROPERTY_BDNAME:
+			if (hal_cb != adapter_prop_bdname) {
+				tester_test_failed();
+				return;
+			}
+			remove_expected_hal_cb();
+			break;
+		case BT_PROPERTY_UUIDS:
+			if (hal_cb != adapter_prop_uuids) {
+				tester_test_failed();
+				return;
+			}
+			remove_expected_hal_cb();
+			break;
+		case BT_PROPERTY_CLASS_OF_DEVICE:
+			if (hal_cb != adapter_prop_cod) {
+				tester_test_failed();
+				return;
+			}
+			remove_expected_hal_cb();
+			break;
+		case BT_PROPERTY_TYPE_OF_DEVICE:
+			if (hal_cb != adapter_prop_bdaddr) {
+				tester_test_failed();
+				return;
+			}
+			remove_expected_hal_cb();
+			break;
+		case BT_PROPERTY_SERVICE_RECORD:
+			if (hal_cb != adapter_prop_service_record) {
+				tester_test_failed();
+				return;
+			}
+			remove_expected_hal_cb();
+			break;
+		case BT_PROPERTY_ADAPTER_SCAN_MODE:
+			if (hal_cb != adapter_prop_scan_mode) {
+				tester_test_failed();
+				return;
+			}
+			remove_expected_hal_cb();
+			break;
+		case BT_PROPERTY_ADAPTER_BONDED_DEVICES:
+			if (hal_cb != adapter_prop_bonded_devices) {
+				tester_test_failed();
+				return;
+			}
+			remove_expected_hal_cb();
+			break;
+		case BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT:
+			if (hal_cb != adapter_prop_disc_timeout) {
+				tester_test_failed();
+				return;
+			}
+			remove_expected_hal_cb();
+			break;
+		default:
+			break;
+		}
+	}
+}
+
+static const struct generic_data bluetooth_enable_success_test = {
+	.expected_hal_callbacks = {adapter_prop_bdaddr, adapter_prop_bdname,
+			adapter_prop_uuids, adapter_prop_cod,
+			adapter_prop_scan_mode, adapter_prop_disc_timeout,
+			adapter_state_changed_on, adapter_test_end}
+};
+
 static bt_callbacks_t bt_callbacks = {
 	.size = sizeof(bt_callbacks),
-	.adapter_state_changed_cb = NULL,
-	.adapter_properties_cb = NULL,
+	.adapter_state_changed_cb = adapter_state_changed_cb,
+	.adapter_properties_cb = adapter_properties_cb,
 	.remote_device_properties_cb = NULL,
 	.device_found_cb = NULL,
 	.discovery_state_changed_cb = NULL,
@@ -343,12 +552,20 @@ static void teardown(const void *test_data)
 		data->emulator_thread = 0;
 	}
 
+	if (data->expected_callbacks)
+		g_slist_free(data->expected_callbacks);
+
 	tester_teardown_complete();
 }
 
-static void pass_test(const void *test_data)
+static void test_enable(const void *test_data)
 {
-	tester_test_passed();
+	struct test_data *data = tester_get_data();
+
+	hal_cb_init();
+	mgmt_cb_init(data);
+
+	data->if_bluetooth->enable();
 }
 
 #define test_bredrle(name, data, test_setup, test, test_teardown) \
@@ -368,7 +585,8 @@ int main(int argc, char *argv[])
 {
 	tester_init(&argc, &argv);
 
-	test_bredrle("test", NULL, setup, pass_test, teardown);
+	test_bredrle("Test Enable - Success", &bluetooth_enable_success_test,
+						setup, test_enable, teardown);
 
 	return tester_run();
 }
-- 
1.8.4.2


^ permalink raw reply related

* [PATCH 4/6] android: Add stack initialization of stack in setup
From: Grzegorz Kolodziejczyk @ 2013-11-28  9:34 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Marcin Kraglak
In-Reply-To: <1385631296-2856-1-git-send-email-grzegorz.kolodziejczyk@tieto.com>

From: Marcin Kraglak <marcin.kraglak@tieto.com>

This add stack initialization and cleanup in setup/teardown.

Change-Id: I05c622b8e42a5d604e276d0a77d41c9bc7a6045e
---
 android/Makefile.am      |  8 ++++--
 android/android-tester.c | 69 +++++++++++++++++++++++++++++++++++++++++++++---
 2 files changed, 71 insertions(+), 6 deletions(-)

diff --git a/android/Makefile.am b/android/Makefile.am
index b19ab4e..e71857e 100644
--- a/android/Makefile.am
+++ b/android/Makefile.am
@@ -90,9 +90,13 @@ android_android_tester_SOURCES = emulator/btdev.h emulator/btdev.c \
 				src/shared/mgmt.h src/shared/mgmt.c \
 				src/shared/hciemu.h src/shared/hciemu.c \
 				src/shared/tester.h src/shared/tester.c \
-				android/android-tester.c
+				android/hal-utils.h android/hal-utils.c \
+				android/client/hwmodule.c android/android-tester.c
 
-android_android_tester_LDADD = lib/libbluetooth-internal.la @GLIB_LIBS@
+android_android_tester_CFLAGS = $(AM_CFLAGS) -I$(srcdir)/android
+
+android_android_tester_LDADD = lib/libbluetooth-internal.la \
+				android/libhal-internal.la @GLIB_LIBS@
 
 android_android_tester_LDFLAGS = -pthread
 
diff --git a/android/android-tester.c b/android/android-tester.c
index 16e8ec0..5e5afe0 100644
--- a/android/android-tester.c
+++ b/android/android-tester.c
@@ -32,6 +32,9 @@
 #include "src/shared/mgmt.h"
 #include "src/shared/hciemu.h"
 
+#include <hardware/hardware.h>
+#include <hardware/bluetooth.h>
+
 #define WAIT_FOR_CONDITION_TIME 2 /* in seconds */
 
 static pthread_cond_t emulator_cond = PTHREAD_COND_INITIALIZER;
@@ -44,6 +47,7 @@ struct test_data {
 	enum hciemu_type hciemu_type;
 	void *test_data;
 	pthread_t emulator_thread;
+	const bt_interface_t *if_bluetooth;
 };
 
 static void read_info_callback(uint8_t status, uint16_t length,
@@ -253,10 +257,30 @@ static void *emulator(void *user_data)
 	return NULL;
 }
 
+static bt_callbacks_t bt_callbacks = {
+	.size = sizeof(bt_callbacks),
+	.adapter_state_changed_cb = NULL,
+	.adapter_properties_cb = NULL,
+	.remote_device_properties_cb = NULL,
+	.device_found_cb = NULL,
+	.discovery_state_changed_cb = NULL,
+	.pin_request_cb = NULL,
+	.ssp_request_cb = NULL,
+	.bond_state_changed_cb = NULL,
+	.acl_state_changed_cb = NULL,
+	.thread_evt_cb = NULL,
+	.dut_mode_recv_cb = NULL,
+	.le_test_mode_cb = NULL
+};
+
 static void setup(const void *test_data)
 {
 	struct test_data *data = tester_get_data();
+	const hw_module_t *module;
+	hw_device_t *device;
+	bt_status_t status;
 	struct timespec ts;
+	int err;
 
 	clock_gettime(CLOCK_REALTIME, &ts);
 	ts.tv_sec += WAIT_FOR_CONDITION_TIME;
@@ -269,19 +293,56 @@ static void setup(const void *test_data)
 	}
 
 	if (pthread_cond_timedwait(&emulator_cond, &emulator_mutex,
-								&ts))
+								&ts)) {
 		tester_setup_failed();
-	else
-		tester_setup_complete();
+		pthread_mutex_unlock(&emulator_mutex);
+		return;
+	}
 
 	pthread_mutex_unlock(&emulator_mutex);
+
+	err = hw_get_module(BT_HARDWARE_MODULE_ID, &module);
+	if (err) {
+		tester_setup_failed();
+		return;
+	}
+
+	err = module->methods->open(module, BT_HARDWARE_MODULE_ID, &device);
+	if (err) {
+		tester_setup_failed();
+		return;
+	}
+
+	data->if_bluetooth = ((bluetooth_device_t *)
+					device)->get_bluetooth_interface();
+	if (!data->if_bluetooth) {
+		tester_setup_failed();
+		return;
+	}
+
+	status = data->if_bluetooth->init(&bt_callbacks);
+	if (status != BT_STATUS_SUCCESS) {
+		data->if_bluetooth = NULL;
+		tester_setup_failed();
+	}
+
+	tester_setup_complete();
 }
 
 static void teardown(const void *test_data)
 {
 	struct test_data *data = tester_get_data();
 
-	pthread_join(data->emulator_thread, NULL);
+	if (data->if_bluetooth) {
+		data->if_bluetooth->cleanup();
+		data->if_bluetooth = NULL;
+	}
+
+	if (data->emulator_thread) {
+		pthread_join(data->emulator_thread, NULL);
+		data->emulator_thread = 0;
+	}
+
 	tester_teardown_complete();
 }
 
-- 
1.8.4.2


^ permalink raw reply related

* [PATCH 3/6] android: Start emulator in separate thread
From: Grzegorz Kolodziejczyk @ 2013-11-28  9:34 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Marcin Kraglak
In-Reply-To: <1385631296-2856-1-git-send-email-grzegorz.kolodziejczyk@tieto.com>

From: Marcin Kraglak <marcin.kraglak@tieto.com>

This is needed because bluetooth->init call is blocking,
and we have to emulate normal behaviour of android environment.
That thread will exit if it won't receive any message in 2 sec
or when bluetoothd will exit. It will be joined in teardown.

Change-Id: I72ebad714cf1b9ca6792c817c0b3ab7d42630998
---
 android/Makefile.am      |   2 +
 android/android-tester.c | 125 ++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 126 insertions(+), 1 deletion(-)

diff --git a/android/Makefile.am b/android/Makefile.am
index 905032d..b19ab4e 100644
--- a/android/Makefile.am
+++ b/android/Makefile.am
@@ -94,6 +94,8 @@ android_android_tester_SOURCES = emulator/btdev.h emulator/btdev.c \
 
 android_android_tester_LDADD = lib/libbluetooth-internal.la @GLIB_LIBS@
 
+android_android_tester_LDFLAGS = -pthread
+
 endif
 
 EXTRA_DIST += android/Android.mk android/hal-ipc-api.txt android/README \
diff --git a/android/android-tester.c b/android/android-tester.c
index 48e408d..16e8ec0 100644
--- a/android/android-tester.c
+++ b/android/android-tester.c
@@ -15,9 +15,15 @@
  *
  */
 
+#include <stdlib.h>
 #include <unistd.h>
 
 #include <glib.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/un.h>
+#include <pthread.h>
 
 #include "lib/bluetooth.h"
 #include "lib/mgmt.h"
@@ -26,12 +32,18 @@
 #include "src/shared/mgmt.h"
 #include "src/shared/hciemu.h"
 
+#define WAIT_FOR_CONDITION_TIME 2 /* in seconds */
+
+static pthread_cond_t emulator_cond = PTHREAD_COND_INITIALIZER;
+static pthread_mutex_t emulator_mutex = PTHREAD_MUTEX_INITIALIZER;
+
 struct test_data {
 	struct mgmt *mgmt;
 	uint16_t mgmt_index;
 	struct hciemu *hciemu;
 	enum hciemu_type hciemu_type;
 	void *test_data;
+	pthread_t emulator_thread;
 };
 
 static void read_info_callback(uint8_t status, uint16_t length,
@@ -162,6 +174,117 @@ static void test_post_teardown(const void *test_data)
 	data->hciemu = NULL;
 }
 
+static void bluetoothd_start(void)
+{
+	struct test_data *data = tester_get_data();
+	char prg_name[PATH_MAX + 1];
+	char index[8];
+	char *prg_argv[4];
+	pid_t pid;
+	int status;
+
+	snprintf(prg_name, sizeof(prg_name), "%s/%s", "android", "bluetoothd");
+	snprintf(index, sizeof(index), "%d", data->mgmt_index);
+
+	prg_argv[0] = prg_name;
+	prg_argv[1] = "-i";
+	prg_argv[2] = index;
+	prg_argv[3] = NULL;
+
+	pid = fork();
+	if (pid < 0) {
+		perror("Failed to fork new process");
+		return;
+	}
+
+	if (pid == 0) {
+		if (!tester_use_debug())
+			fclose(stderr);
+
+		execve(prg_argv[0], prg_argv, NULL);
+		exit(0);
+	}
+
+	pid = waitpid(-1, &status, 0);
+}
+
+static void *emulator(void *user_data)
+{
+	static const char SYSTEM_SOCKET_PATH[] = "\0android_system";
+	char buf[4096];
+	struct sockaddr_un addr;
+	struct timeval tv;
+	int fd;
+	ssize_t len;
+
+	fd = socket(PF_LOCAL, SOCK_DGRAM | SOCK_CLOEXEC, 0);
+	if (fd < 0)
+		return NULL;
+
+	tv.tv_sec = WAIT_FOR_CONDITION_TIME;
+	tv.tv_usec = 0;
+	setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(tv));
+
+	memset(&addr, 0, sizeof(addr));
+	addr.sun_family = AF_UNIX;
+	memcpy(addr.sun_path, SYSTEM_SOCKET_PATH, sizeof(SYSTEM_SOCKET_PATH));
+
+	if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
+		perror("Failed to bind system socket");
+		close(fd);
+		pthread_exit(NULL);
+		return NULL;
+	}
+
+	pthread_mutex_lock(&emulator_mutex);
+	pthread_cond_signal(&emulator_cond);
+	pthread_mutex_unlock(&emulator_mutex);
+
+	len = read(fd, buf, sizeof(buf));
+	if (len <= 0 || (strcmp(buf, "ctl.start=bluetoothd"))) {
+		close(fd);
+		pthread_exit(NULL);
+		return NULL;
+	}
+
+	close(fd);
+	bluetoothd_start();
+	pthread_exit(NULL);
+	return NULL;
+}
+
+static void setup(const void *test_data)
+{
+	struct test_data *data = tester_get_data();
+	struct timespec ts;
+
+	clock_gettime(CLOCK_REALTIME, &ts);
+	ts.tv_sec += WAIT_FOR_CONDITION_TIME;
+
+	pthread_mutex_lock(&emulator_mutex);
+
+	if (pthread_create(&data->emulator_thread, NULL, emulator, NULL)) {
+		tester_setup_failed();
+		return;
+	}
+
+	if (pthread_cond_timedwait(&emulator_cond, &emulator_mutex,
+								&ts))
+		tester_setup_failed();
+	else
+		tester_setup_complete();
+
+	pthread_mutex_unlock(&emulator_mutex);
+}
+
+static void teardown(const void *test_data)
+{
+	struct test_data *data = tester_get_data();
+
+	pthread_join(data->emulator_thread, NULL);
+	tester_teardown_complete();
+}
+
 static void pass_test(const void *test_data)
 {
 	tester_test_passed();
@@ -184,7 +307,7 @@ int main(int argc, char *argv[])
 {
 	tester_init(&argc, &argv);
 
-	test_bredrle("test", NULL, NULL, pass_test, NULL);
+	test_bredrle("test", NULL, setup, pass_test, teardown);
 
 	return tester_run();
 }
-- 
1.8.4.2


^ permalink raw reply related

* [PATCH 2/6] android: Add pre-setup and post-teardown routines
From: Grzegorz Kolodziejczyk @ 2013-11-28  9:34 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Marcin Kraglak
In-Reply-To: <1385631296-2856-1-git-send-email-grzegorz.kolodziejczyk@tieto.com>

From: Marcin Kraglak <marcin.kraglak@tieto.com>

This will add hciemu initialization and cleanup. These functions
will be called to create hci emulator and cleanup it.

Change-Id: Id9e32ee725948ac1d313041ab136f02d17d00fed
---
 android/Makefile.am      |  10 ++-
 android/android-tester.c | 171 ++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 179 insertions(+), 2 deletions(-)

diff --git a/android/Makefile.am b/android/Makefile.am
index 9390422..905032d 100644
--- a/android/Makefile.am
+++ b/android/Makefile.am
@@ -84,7 +84,15 @@ android_haltest_LDFLAGS = -pthread
 
 noinst_PROGRAMS += android/android-tester
 
-android_android_tester_SOURCES = android/android-tester.c
+android_android_tester_SOURCES = emulator/btdev.h emulator/btdev.c \
+				emulator/bthost.h emulator/bthost.c \
+				src/shared/util.h src/shared/util.c \
+				src/shared/mgmt.h src/shared/mgmt.c \
+				src/shared/hciemu.h src/shared/hciemu.c \
+				src/shared/tester.h src/shared/tester.c \
+				android/android-tester.c
+
+android_android_tester_LDADD = lib/libbluetooth-internal.la @GLIB_LIBS@
 
 endif
 
diff --git a/android/android-tester.c b/android/android-tester.c
index f5c42b0..48e408d 100644
--- a/android/android-tester.c
+++ b/android/android-tester.c
@@ -15,7 +15,176 @@
  *
  */
 
+#include <unistd.h>
+
+#include <glib.h>
+
+#include "lib/bluetooth.h"
+#include "lib/mgmt.h"
+
+#include "src/shared/tester.h"
+#include "src/shared/mgmt.h"
+#include "src/shared/hciemu.h"
+
+struct test_data {
+	struct mgmt *mgmt;
+	uint16_t mgmt_index;
+	struct hciemu *hciemu;
+	enum hciemu_type hciemu_type;
+	void *test_data;
+};
+
+static void read_info_callback(uint8_t status, uint16_t length,
+					const void *param, void *user_data)
+{
+	struct test_data *data = tester_get_data();
+	const struct mgmt_rp_read_info *rp = param;
+	char addr[18];
+	uint16_t manufacturer;
+	uint32_t supported_settings, current_settings;
+
+	tester_print("Read Info callback");
+	tester_print("  Status: 0x%02x", status);
+
+	if (status || !param) {
+		tester_pre_setup_failed();
+		return;
+	}
+
+	ba2str(&rp->bdaddr, addr);
+	manufacturer = btohs(rp->manufacturer);
+	supported_settings = btohl(rp->supported_settings);
+	current_settings = btohl(rp->current_settings);
+
+	tester_print("  Address: %s", addr);
+	tester_print("  Version: 0x%02x", rp->version);
+	tester_print("  Manufacturer: 0x%04x", manufacturer);
+	tester_print("  Supported settings: 0x%08x", supported_settings);
+	tester_print("  Current settings: 0x%08x", current_settings);
+	tester_print("  Class: 0x%02x%02x%02x",
+			rp->dev_class[2], rp->dev_class[1], rp->dev_class[0]);
+	tester_print("  Name: %s", rp->name);
+	tester_print("  Short name: %s", rp->short_name);
+
+	if (strcmp(hciemu_get_address(data->hciemu), addr)) {
+		tester_pre_setup_failed();
+		return;
+	}
+
+	tester_pre_setup_complete();
+}
+
+static void index_added_callback(uint16_t index, uint16_t length,
+					const void *param, void *user_data)
+{
+	struct test_data *data = tester_get_data();
+
+	tester_print("Index Added callback");
+	tester_print("  Index: 0x%04x", index);
+
+	data->mgmt_index = index;
+
+	mgmt_send(data->mgmt, MGMT_OP_READ_INFO, data->mgmt_index, 0, NULL,
+					read_info_callback, NULL, NULL);
+}
+
+static void index_removed_callback(uint16_t index, uint16_t length,
+					const void *param, void *user_data)
+{
+	struct test_data *data = tester_get_data();
+
+	tester_print("Index Removed callback");
+	tester_print("  Index: 0x%04x", index);
+
+	if (index != data->mgmt_index)
+		return;
+
+	mgmt_unregister_index(data->mgmt, data->mgmt_index);
+
+	mgmt_unref(data->mgmt);
+	data->mgmt = NULL;
+
+	tester_post_teardown_complete();
+}
+
+static void read_index_list_callback(uint8_t status, uint16_t length,
+					const void *param, void *user_data)
+{
+	struct test_data *data = tester_get_data();
+
+	tester_print("Read Index List callback");
+	tester_print("  Status: 0x%02x", status);
+
+	if (status || !param) {
+		tester_pre_setup_failed();
+		return;
+	}
+
+	mgmt_register(data->mgmt, MGMT_EV_INDEX_ADDED, MGMT_INDEX_NONE,
+					index_added_callback, NULL, NULL);
+
+	mgmt_register(data->mgmt, MGMT_EV_INDEX_REMOVED, MGMT_INDEX_NONE,
+					index_removed_callback, NULL, NULL);
+
+	data->hciemu = hciemu_new(data->hciemu_type);
+	if (!data->hciemu) {
+		tester_warn("Failed to setup HCI emulation");
+		tester_pre_setup_failed();
+		return;
+	}
+
+	tester_print("New hciemu instance created");
+}
+
+static void test_pre_setup(const void *test_data)
+{
+	struct test_data *data = tester_get_data();
+
+	if (!tester_use_debug())
+		fclose(stderr);
+
+	data->mgmt = mgmt_new_default();
+	if (!data->mgmt) {
+		tester_warn("Failed to setup management interface");
+		tester_pre_setup_failed();
+		return;
+	}
+
+	mgmt_send(data->mgmt, MGMT_OP_READ_INDEX_LIST, MGMT_INDEX_NONE, 0,
+				NULL, read_index_list_callback, NULL, NULL);
+}
+
+static void test_post_teardown(const void *test_data)
+{
+	struct test_data *data = tester_get_data();
+
+	hciemu_unref(data->hciemu);
+	data->hciemu = NULL;
+}
+
+static void pass_test(const void *test_data)
+{
+	tester_test_passed();
+}
+
+#define test_bredrle(name, data, test_setup, test, test_teardown) \
+	do { \
+		struct test_data *user; \
+		user = g_malloc0(sizeof(struct test_data)); \
+		if (!user) \
+			break; \
+		user->hciemu_type = HCIEMU_TYPE_BREDRLE; \
+		user->test_data = data; \
+		tester_add_full(name, data, test_pre_setup, test_setup, \
+				test, test_teardown, test_post_teardown, \
+							3, user, g_free); \
+	} while (0)
+
 int main(int argc, char *argv[])
 {
-	return 0;
+	tester_init(&argc, &argv);
+
+	test_bredrle("test", NULL, NULL, pass_test, NULL);
+
+	return tester_run();
 }
-- 
1.8.4.2


^ permalink raw reply related

* [PATCH] Whitespace characters
From: Grzegorz Kolodziejczyk @ 2013-11-28  9:34 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1385631296-2856-1-git-send-email-grzegorz.kolodziejczyk@tieto.com>

---
 android/bt-hal-tester.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/android/bt-hal-tester.c b/android/bt-hal-tester.c
index 8bcb901..fab987b 100644
--- a/android/bt-hal-tester.c
+++ b/android/bt-hal-tester.c
@@ -86,7 +86,7 @@ static void read_info_callback(uint8_t status, uint16_t length,
 		tester_pre_setup_failed();
 		return;
 	}
-	
+
 	tester_pre_setup_complete();
 }
 
@@ -275,24 +275,24 @@ static void setup(const void *test_data)
 	bt_status_t status;
 	const hw_module_t *module;
 	hw_device_t *device;
-	
+
 	clock_gettime(CLOCK_REALTIME, &ts);
 	ts.tv_sec += WAIT_FOR_CONDITION_TIME;
 
 	pthread_mutex_lock(&emulator_mutex);
-	
+
 	if (pthread_create(&data->emulator_thread, NULL, emulator, NULL)) {
 		tester_setup_failed();
 		return;
 	}
 	if (pthread_cond_timedwait(&emulator_started_cond, &emulator_mutex, &ts)
-																	< 0) {
+									< 0) {
 		tester_setup_failed();
 		return;
 	} else {
 		data->emulator_started = true;
 	}
-	
+
 	pthread_mutex_unlock(&emulator_mutex);
 
 	err = hw_get_module(BT_HARDWARE_MODULE_ID, &module);
@@ -320,14 +320,14 @@ static void setup(const void *test_data)
 		data->if_bluetooth = NULL;
 		tester_setup_failed();
 	}
-	
+
 	tester_setup_complete();
 }
 
 static void teardown(const void *test_data)
 {
 	struct test_data *data = tester_get_data();
-	
+
 	if (data->if_bluetooth)
 		data->if_bluetooth->cleanup();
 
-- 
1.8.4.2


^ permalink raw reply related

* [PATCH 1/6] android: Add android-tester
From: Grzegorz Kolodziejczyk @ 2013-11-28  9:34 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Marcin Kraglak
In-Reply-To: <1385631296-2856-1-git-send-email-grzegorz.kolodziejczyk@tieto.com>

From: Marcin Kraglak <marcin.kraglak@tieto.com>

This commit add android-tester.c to tree and Makefile.am.
This will contain set of unit tests for testing android daemon.

Change-Id: I0acf021aa33a0d7531f1e9faae8cd0b68d6b0438
---
 android/Makefile.am      |  4 ++++
 android/android-tester.c | 21 +++++++++++++++++++++
 2 files changed, 25 insertions(+)
 create mode 100644 android/android-tester.c

diff --git a/android/Makefile.am b/android/Makefile.am
index 94d231f..9390422 100644
--- a/android/Makefile.am
+++ b/android/Makefile.am
@@ -82,6 +82,10 @@ android_haltest_CFLAGS = $(AM_CFLAGS) -I$(srcdir)/android \
 
 android_haltest_LDFLAGS = -pthread
 
+noinst_PROGRAMS += android/android-tester
+
+android_android_tester_SOURCES = android/android-tester.c
+
 endif
 
 EXTRA_DIST += android/Android.mk android/hal-ipc-api.txt android/README \
diff --git a/android/android-tester.c b/android/android-tester.c
new file mode 100644
index 0000000..f5c42b0
--- /dev/null
+++ b/android/android-tester.c
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ *
+ */
+
+int main(int argc, char *argv[])
+{
+	return 0;
+}
-- 
1.8.4.2


^ permalink raw reply related

* [PATCH 0/6] android: initial code for automated tests
From: Grzegorz Kolodziejczyk @ 2013-11-28  9:34 UTC (permalink / raw)
  To: linux-bluetooth

Hi,

This serie adds initial code for automated android deamon and HAL library
tests. Skeleton and one initial test case is added.

-- 
Best regards,
Grzegorz

Grzegorz Kolodziejczyk (1):
  android: Add basic test and handle mgmt notifications, hal cb

Marcin Kraglak (4):
  android: Add android-tester
  android: Add pre-setup and post-teardown routines
  android: Start emulator in separate thread
  android: Add stack initialization of stack in setup

Szymon Janc (1):
  android: Make HAL logging wrapper print to stderr instead of stdout

 android/Makefile.am      |  18 ++
 android/android-tester.c | 592 +++++++++++++++++++++++++++++++++++++++++++++++
 android/hal-log.h        |   2 +-
 3 files changed, 611 insertions(+), 1 deletion(-)
 create mode 100644 android/android-tester.c

-- 
1.8.4.2


^ permalink raw reply

* [PATCH] android/pics: Add PTS PICS for OPP
From: Jakub Tyszkowski @ 2013-11-28  8:04 UTC (permalink / raw)
  To: linux-bluetooth

PTS PICS for OPP, targeting Android 4.4.

---
 android/Makefile.am  |   3 +-
 android/pics-opp.txt | 184 +++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 186 insertions(+), 1 deletion(-)
 create mode 100644 android/pics-opp.txt

diff --git a/android/Makefile.am b/android/Makefile.am
index 94d231f..38aa00a 100644
--- a/android/Makefile.am
+++ b/android/Makefile.am
@@ -86,4 +86,5 @@ endif
 
 EXTRA_DIST += android/Android.mk android/hal-ipc-api.txt android/README \
 		android/pics-gap.txt android/pics-hid.txt \
-		android/pics-pan.txt android/pics-did.txt
+		android/pics-pan.txt android/pics-did.txt \
+		android/pics-opp.txt
diff --git a/android/pics-opp.txt b/android/pics-opp.txt
new file mode 100644
index 0000000..c0f2ad6
--- /dev/null
+++ b/android/pics-opp.txt
@@ -0,0 +1,184 @@
+OPP PICS for the PTS tool.
+
+* - different than PTS defaults
+# - not yet implemented/supported
+
+M - mandatory
+O - optional
+
+		Roles
+-------------------------------------------------------------------------------
+Parameter Name	Selected	Description
+-------------------------------------------------------------------------------
+TSPC_OPP_1_1	True (*)	Role: Object Push Client.
+TSPC_OPP_1_2	True (*)	Role: Object Push Server.
+-------------------------------------------------------------------------------
+C.1: It is Mandatory to Support at least one of the defined roles.
+-------------------------------------------------------------------------------
+
+
+		Client Profile Version
+-------------------------------------------------------------------------------
+Parameter Name	Selected	Description
+-------------------------------------------------------------------------------
+TSPC_OPP_1b_1	True		Client supports OPP version 1.1. (C.1)
+TSPC_OPP_1b_2	False		Client supports OPP version 1.2. (C.1)
+-------------------------------------------------------------------------------
+C.1: It is mandatory to support at least one of the profile versions.
+-------------------------------------------------------------------------------
+
+
+		Client Application Features
+-------------------------------------------------------------------------------
+Parameter Name	Selected	Description
+-------------------------------------------------------------------------------
+TSPC_OPP_2_1	True		Client: Perform Service Discovery request.
+					(M.1)
+TSPC_OPP_2_2	True		Client: Authentication/PIN exchange supported.
+					(M.1)
+TSPC_OPP_2_2a	True (*)	Client: Require Authentication/PIN by default.
+					(O)
+TSPC_OPP_2_3	True		Client: Object Push is supported. (M.1)
+TSPC_OPP_2_4	True (*)	Client: vCard 2.1 format is supported for
+					Object Push. (C.3)
+TSPC_OPP_2_5	False		Client: vCalender 1.0 format is supported for
+					Object Push. (O)
+TSPC_OPP_2_6	False		Client: vMsg as defined in IrMC 1.1 is supported
+					for Object Push. (O)
+TSPC_OPP_2_7	False		Client: vNote as defined in IrMC 1.1 is
+					supported for Object Push. (O)
+TSPC_OPP_2_8	True (*)	Client: Support content formats other than those
+					declared in TSPC_OPP_2_44 through
+					TSPC_OPP_2_7. (O)
+TSPC_OPP_2_8a	False		Client: Support specific set of other content
+					formats. (C.4)
+TSPC_OPP_2_8b	True (*)	Client: Support all content formats. (C.4)
+TSPC_OPP_2_9	True (*)	Client: Push multiple vCard objects. (O)
+TSPC_OPP_2_9a	False		Client: Push multiple vCard objects using
+					different PUT operations. (C.5)
+TSPC_OPP_2_9b	True (*)	Client: Push multiple vCard objects using the
+					same PUT operation. (C.5)
+TSPC_OPP_2_10	False		Client: Push multiple vCalender objects. (O)
+TSPC_OPP_2_10a	False		Client: Push multiple vMsg objects using
+					different PUT operations. (C.6)
+TSPC_OPP_2_10b	False		Client: Push multiple vMsg objects using the
+					same PUT operation. (C.6)
+TSPC_OPP_2_11	False		Client: Push multiple vMsg objects. (O)
+TSPC_OPP_2_11a	False		Client: Push multiple vMsg objects using
+					different PUT operations. (C.7)
+TSPC_OPP_2_11b	False		Client: Push multiple vMsg objects using the
+					same PUT operation. (C.7)
+TSPC_OPP_2_12	False		Client: Push multiple vNote objects. (O)
+TSPC_OPP_2_12a	False		Client: Push multiple vNote objects using
+					different PUT operations. (C.8)
+TSPC_OPP_2_12b	False		Client: Push multiple vNote objects using the
+					same PUT operation. (C.8)
+TSPC_OPP_2_13	False		Client: Pull business card is supported. (O)
+TSPC_OPP_2_14	False		Client: vCard 2.1 format is supported for
+					Business Card Pull. (C.1)
+TSPC_OPP_2_15	False		Client: Exchange business card is supported. (O)
+TSPC_OPP_2_16	False		Client: vCard 2.1 format is supported for
+					Business Card Exchange (C.2)
+-------------------------------------------------------------------------------
+C.1: Mandatory to Support IF (TSPC_OPP_2_13) Business Card Pull is supported.
+C.2: Mandatory to Support IF (TSPC_OPP_2_15) Business Card Exchange is
+	supported.
+M.1: Mandatory to Support IF (TSPC_OPP_1_1) supported.
+C.3: vCard 2.1 support is required for devices containing phonebook
+	applications. vCard 2.1 support optional for other devices.
+C.4: Mandatory to support one of TSPC_OPP_2_8a or TSPC_OPP_2_8b if TSPC_OPP_2_8
+	is supported. Otherwise, both items are excluded.
+C.5: Mandatory to support at least one of TSPC_OPP_2_9a and TSPC_OPP_2_9b if
+	TSPC_OPP_2_9 is supported. Otherwise, both items are excluded.
+C.6: Mandatory to support at least one of TSPC_OPP_2_10a and TSPC_OPP_2_10b if
+	TSPC_OPP_2_10 is supported. Otherwise, both items are excluded.
+C.7: Mandatory to support at least one of TSPC_OPP_2_11a and TSPC_OPP_2_11b if
+	TSPC_OPP_2_11 is supported. Otherwise, both items are excluded.
+C.8: Mandatory to support at least one of TSPC_OPP_2_12a and TSPC_OPP_2_12b if
+	TSPC_OPP_2_12 is supported. Otherwise, both items are excluded.
+-------------------------------------------------------------------------------
+
+
+		Server Profile Version
+-------------------------------------------------------------------------------
+Parameter Name	Selected	Description
+-------------------------------------------------------------------------------
+TSPC_OPP_2b_1	True		Server supports OPP version 1.1.
+TSPC_OPP_2b_2	False		Server supports OPP version 1.2.
+-------------------------------------------------------------------------------
+C.1: It is mandatory to support at least one of the profile versions.
+-------------------------------------------------------------------------------
+
+
+		Server Application Features
+-------------------------------------------------------------------------------
+Parameter Name	Selected	Description
+-------------------------------------------------------------------------------
+TSPC_OPP_3_1	True		Server: Provide information on supported
+					contents type on service discovery
+					request. (M)
+TSPC_OPP_3_2	True		Server: Authentication/PIN exchange supported.
+					(M)
+TSPC_OPP_3_3	True		Server: Object Push is supported. (M)
+TSPC_OPP_3_3a	True (*)	Server: Receive multiple objects in the same
+					PUT operation. (O)
+TSPC_OPP_3_4	True (*)	Server: vCard 2.1 format is supported for Object
+					Push. (C.3)
+TSPC_OPP_3_5	False		Server: vCalender 1.0 format is supported for
+					Object Push. (O)
+TSPC_OPP_3_6	False		Server: vMsg as defined in IrMC 1.1 is supported
+					for Object Push. (O)
+TSPC_OPP_3_7	False		Server: vNote as defined in IrMC 1.1 is
+					supported for Object Push. (O)
+TSPC_OPP_3_8	True (*)	Server: Support content formats other than those
+					declared in TSPC_OPP_3_4 through
+					TSPC_OPP_3_7. (O)
+TSPC_OPP_3_8a	False		Server: Support specific set of other content
+					formats. (C.4)
+TSPC_OPP_3_8b	True (*)	Server: Support all content formats. (C.4)
+TSPC_OPP_3_9	True (*)	Server: Object Push vCard reject. (O)
+TSPC_OPP_3_10	False		Server: Object Push vCal rejectt. (O)
+TSPC_OPP_3_11	False		Server: Object Push vMsg reject. (O)
+TSPC_OPP_3_12	False		Server: Object Push vNote reject. (O)
+TSPC_OPP_3_13	False		Server: Business card pull is supported. (O.1)
+TSPC_OPP_3_14	False		Server: vCard 2.1 format is supported for
+					Business Card Pull. (C.1)
+TSPC_OPP_3_15	False		Server: Business card pull reject. (O)
+TSPC_OPP_3_16	False		Server: Business card exchange is supported.
+					(O.2)
+TSPC_OPP_3_17	False		Server: vCard 2.1 format is supported for
+					Business Card Exchange (C.2)
+TSPC_OPP_3_18	False		Server: Business card exchange reject. (O)
+-------------------------------------------------------------------------------
+M.1: Mandatory to Support IF (TSPC_OPP_1_2) supported.
+C.2: Mandatory to Support IF (TSPC_OPP_3_16) Business Card Exchange is
+	supported.
+O.1: IF NOT Supported, an error message must be sent on request for Business
+	Card Pull.
+O.2: IF NOT Supported, an error message must be sent on request for Business
+	Card Exchange.
+C.1: Mandatory to Support IF (TSPC_OPP_3_13) Business Card Pull is supported.
+C.3: vCard 2.1 support is required for devices containing phonebook
+	applications. vCard 2.1 support optional for other devices.
+C.4: Mandatory to support one of TSPC_OPP_3_8a or TSPC_OPP_3_8b if TSPC_OPP_3_8
+	is supported. Otherwise, both items are excluded.
+-------------------------------------------------------------------------------
+
+
+		Additional OPP Capabilities
+-------------------------------------------------------------------------------
+Parameter Name	Selected	Description
+-------------------------------------------------------------------------------
+TSPC_OPP_4_1	False		Abort-Push Operation is supported. (O)
+TSPC_OPP_4_2	False		Disconnect of OBEX session should be tested.
+TSPC_OPP_4_3	False		Multiple vCards transferred as a single vObject
+					is supported. (C.1)
+TSPC_OPP_4_4	False		Multiple vCards transfer is supported. (C.1)
+TSPC_OPP_4_5	False		vCards with multiple Phone Number Fields is
+					supported. (C.1)
+TSPC_OPP_4_6	False		Server supports Push vCal to Different Time
+					Zone. (C.1)
+TSPC_ALL	False		Turn on all test cases.
+-------------------------------------------------------------------------------
+C.1: Optional if TSPC_OPP_1_2 is supported, otherwise excluded.
+-------------------------------------------------------------------------------
-- 
1.8.4.1


^ permalink raw reply related

* Re: [RFC] build: Force GLib version check while building in maintainer mode
From: Johan Hedberg @ 2013-11-28  7:44 UTC (permalink / raw)
  To: Szymon Janc; +Cc: linux-bluetooth
In-Reply-To: <1385567096-27261-1-git-send-email-szymon.janc@tieto.com>

Hi Szymon,

On Wed, Nov 27, 2013, Szymon Janc wrote:
> This will allow to catch up build errors introduced by using GLib API
> introduced in newer GLib than minimal required even if building with
> newer version.
> ---
>  acinclude.m4 | 2 ++
>  1 file changed, 2 insertions(+)

Seems like a good idea. Applied. Thanks.

Johan

^ permalink raw reply

* [PATCH] Bluetooth: Add support for Toshiba Bluetooth device [0930:0220]
From: Marco Piazza @ 2013-11-27 23:15 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Marco Piazza

This patch adds support for new Toshiba Bluetooth device.

T:  Bus=05 Lev=01 Prnt=01 Port=02 Cnt=02 Dev#=  4 Spd=12  MxCh= 0
D:  Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs=  1
P:  Vendor=0930 ProdID=0220 Rev=00.02
C:  #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=100mA
I:  If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
I:  If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb

Signed-off-by: Marco Piazza <mpiazza@gmail.com>
---
 drivers/bluetooth/ath3k.c | 2 ++
 drivers/bluetooth/btusb.c | 1 +
 2 files changed, 3 insertions(+)

diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c
index d3fdc32..106d1d8 100644
--- a/drivers/bluetooth/ath3k.c
+++ b/drivers/bluetooth/ath3k.c
@@ -88,6 +88,7 @@ static const struct usb_device_id ath3k_table[] = {
 	{ USB_DEVICE(0x0CF3, 0xE004) },
 	{ USB_DEVICE(0x0CF3, 0xE005) },
 	{ USB_DEVICE(0x0930, 0x0219) },
+	{ USB_DEVICE(0x0930, 0x0220) },
 	{ USB_DEVICE(0x0489, 0xe057) },
 	{ USB_DEVICE(0x13d3, 0x3393) },
 	{ USB_DEVICE(0x0489, 0xe04e) },
@@ -132,6 +133,7 @@ static const struct usb_device_id ath3k_blist_tbl[] = {
 	{ USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0cf3, 0xe005), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x0930, 0x0220), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0489, 0xe057), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0489, 0xe04e), .driver_info = BTUSB_ATH3012 },
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index bfbcc5a..9f7e539 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -155,6 +155,7 @@ static const struct usb_device_id blacklist_table[] = {
 	{ USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0cf3, 0xe005), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x0930, 0x0220), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0489, 0xe057), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0489, 0xe04e), .driver_info = BTUSB_ATH3012 },
-- 
1.8.4.rc3


^ permalink raw reply related

* [RFC BlueZ v0 17/17] bluetooth.conf: Add ObjectManager interface
From: Claudio Takahasi @ 2013-11-27 20:50 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1385585457-26951-1-git-send-email-claudio.takahasi@openbossa.org>

---
 src/bluetooth.conf | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/bluetooth.conf b/src/bluetooth.conf
index 0495200..ad8891a 100644
--- a/src/bluetooth.conf
+++ b/src/bluetooth.conf
@@ -18,6 +18,7 @@
     <allow send_interface="org.bluez.Profile1"/>
     <allow send_interface="org.bluez.HeartRateWatcher1"/>
     <allow send_interface="org.bluez.CyclingSpeedWatcher1"/>
+    <allow send_interface="org.freedesktop.DBus.ObjectManager"/>
   </policy>
 
   <policy at_console="true">
-- 
1.8.3.1


^ permalink raw reply related

* [RFC BlueZ v0 16/17] gatttool: Add unix socket support for interactive mode
From: Claudio Takahasi @ 2013-11-27 20:50 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1385585457-26951-1-git-send-email-claudio.takahasi@openbossa.org>

This patch allows running GATT operations over unix socket on
interactive mode.
---
 attrib/interactive.c | 18 ++++++++++--------
 1 file changed, 10 insertions(+), 8 deletions(-)

diff --git a/attrib/interactive.c b/attrib/interactive.c
index 5bd27af..d89b494 100644
--- a/attrib/interactive.c
+++ b/attrib/interactive.c
@@ -84,7 +84,7 @@ static char *get_prompt(void)
 	if (opt_dst)
 		g_string_append_printf(prompt, "[%17s]", opt_dst);
 	else
-		g_string_append_printf(prompt, "[%17s]", "");
+		g_string_append_printf(prompt, "[LOCAL]");
 
 	if (conn_state == STATE_CONNECTED)
 		g_string_append(prompt, COLOR_OFF);
@@ -406,15 +406,17 @@ static void cmd_connect(int argcp, char **argvp)
 			opt_dst_type = g_strdup("public");
 	}
 
-	if (opt_dst == NULL) {
-		error("Remote Bluetooth address required\n");
-		return;
+	if (opt_dst) {
+
+		rl_printf("Attempting to connect to %s\n", opt_dst);
+		set_state(STATE_CONNECTING);
+		iochannel = gatt_connect(opt_src, opt_dst, opt_dst_type, opt_sec_level,
+				opt_psm, opt_mtu, connect_cb, &gerr);
+	} else {
+		rl_printf("Local connection\n");
+		iochannel = unix_connect(connect_cb, &gerr);
 	}
 
-	rl_printf("Attempting to connect to %s\n", opt_dst);
-	set_state(STATE_CONNECTING);
-	iochannel = gatt_connect(opt_src, opt_dst, opt_dst_type, opt_sec_level,
-					opt_psm, opt_mtu, connect_cb, &gerr);
 	if (iochannel == NULL) {
 		set_state(STATE_DISCONNECTED);
 		error("%s\n", gerr->message);
-- 
1.8.3.1


^ permalink raw reply related

* [RFC BlueZ v0 15/17] gatttool: Add unix socket connect
From: Claudio Takahasi @ 2013-11-27 20:50 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1385585457-26951-1-git-send-email-claudio.takahasi@openbossa.org>

This patch adds the initial support for GATT procedures over unix
socket transport on command line mode (one-shot command). Temporary
solution to allow local GATT procedures testing.
---
 attrib/gatttool.c | 27 ++++++++++++++++++++-------
 attrib/gatttool.h |  1 +
 attrib/utils.c    | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 75 insertions(+), 7 deletions(-)

diff --git a/attrib/gatttool.c b/attrib/gatttool.c
index f211dcd..65fba19 100644
--- a/attrib/gatttool.c
+++ b/attrib/gatttool.c
@@ -29,7 +29,6 @@
 #include <errno.h>
 #include <glib.h>
 #include <stdlib.h>
-#include <unistd.h>
 
 #include <bluetooth/bluetooth.h>
 #include <bluetooth/hci.h>
@@ -53,6 +52,7 @@ static int opt_end = 0xffff;
 static int opt_handle = -1;
 static int opt_mtu = 0;
 static int opt_psm = 0;
+static gboolean opt_local = FALSE;
 static gboolean opt_primary = FALSE;
 static gboolean opt_characteristics = FALSE;
 static gboolean opt_char_read = FALSE;
@@ -512,6 +512,8 @@ static GOptionEntry options[] = {
 		"Specify local adapter interface", "hciX" },
 	{ "device", 'b', 0, G_OPTION_ARG_STRING, &opt_dst,
 		"Specify remote Bluetooth address", "MAC" },
+	{ "local", 'L', 0, G_OPTION_ARG_NONE, &opt_local,
+		"Use unix socket transport (local communication)", NULL },
 	{ "addr-type", 't', 0, G_OPTION_ARG_STRING, &opt_dst_type,
 		"Set LE address type. Default: public", "[public | random]"},
 	{ "mtu", 'm', 0, G_OPTION_ARG_INT, &opt_mtu,
@@ -564,6 +566,11 @@ int main(int argc, char *argv[])
 		g_clear_error(&gerr);
 	}
 
+	if (opt_local) {
+		opt_src = NULL;
+		opt_dst = NULL;
+	}
+
 	if (opt_interactive) {
 		interactive(opt_src, opt_dst, opt_dst_type, opt_psm);
 		goto done;
@@ -589,14 +596,20 @@ int main(int argc, char *argv[])
 		goto done;
 	}
 
-	if (opt_dst == NULL) {
-		g_print("Remote Bluetooth address required\n");
-		got_error = TRUE;
-		goto done;
+	if (opt_local)
+		chan = unix_connect(connect_cb, &gerr);
+	else {
+		if (opt_dst == NULL) {
+			g_print("Remote Bluetooth address required\n");
+			got_error = TRUE;
+			goto done;
+		}
+
+		chan = gatt_connect(opt_src, opt_dst, opt_dst_type,
+					opt_sec_level, opt_psm, opt_mtu,
+					connect_cb, &gerr);
 	}
 
-	chan = gatt_connect(opt_src, opt_dst, opt_dst_type, opt_sec_level,
-					opt_psm, opt_mtu, connect_cb, &gerr);
 	if (chan == NULL) {
 		g_printerr("%s\n", gerr->message);
 		g_clear_error(&gerr);
diff --git a/attrib/gatttool.h b/attrib/gatttool.h
index 8f0913c..be8e236 100644
--- a/attrib/gatttool.h
+++ b/attrib/gatttool.h
@@ -27,4 +27,5 @@ GIOChannel *gatt_connect(const char *src, const char *dst,
 			const char *dst_type, const char *sec_level,
 			int psm, int mtu, BtIOConnect connect_cb,
 			GError **gerr);
+GIOChannel *unix_connect(BtIOConnect connect_cb, GError **gerr);
 size_t gatt_attr_data_from_string(const char *str, uint8_t **data);
diff --git a/attrib/utils.c b/attrib/utils.c
index 77bab27..de7b00a 100644
--- a/attrib/utils.c
+++ b/attrib/utils.c
@@ -25,7 +25,12 @@
 #include "config.h"
 #endif
 
+#include <errno.h>
 #include <stdlib.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+
 #include <glib.h>
 
 #include <bluetooth/bluetooth.h>
@@ -101,6 +106,55 @@ GIOChannel *gatt_connect(const char *src, const char *dst,
 	return chan;
 }
 
+static gboolean unix_connect_cb(GIOChannel *io, GIOCondition cond,
+							gpointer user_data)
+{
+	BtIOConnect connect_cb = user_data;
+	GError *gerr;
+
+	if (cond & (G_IO_HUP | G_IO_ERR | G_IO_NVAL)) {
+		gerr = g_error_new_literal(G_IO_CHANNEL_ERROR,
+						G_IO_CHANNEL_ERROR_FAILED,
+						"connection attempt failed");
+		connect_cb(io, gerr, user_data);
+		g_clear_error(&gerr);
+	} else {
+		connect_cb(io, NULL, user_data);
+	}
+
+	return FALSE;
+}
+
+GIOChannel *unix_connect(BtIOConnect connect_cb, GError **gerr)
+{
+	GIOChannel *io;
+	struct sockaddr_un uaddr  = {
+		.sun_family	= AF_UNIX,
+		.sun_path	= "\0/bluetooth/unix_att",
+	};
+	int sk;
+
+	sk = socket(AF_UNIX, SOCK_SEQPACKET | SOCK_CLOEXEC , 0);
+	if (sk < 0) {
+		g_set_error_literal(gerr, G_IO_CHANNEL_ERROR,
+				G_IO_CHANNEL_ERROR_FAILED, strerror(errno));
+		return NULL;
+	}
+
+	if (connect(sk, (struct sockaddr *) &uaddr, sizeof(uaddr)) < 0) {
+		g_set_error_literal(gerr, G_IO_CHANNEL_ERROR,
+				G_IO_CHANNEL_ERROR_FAILED, strerror(errno));
+		close(sk);
+		return NULL;
+	}
+
+	io = g_io_channel_unix_new(sk);
+	g_io_add_watch(io, G_IO_OUT | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
+						unix_connect_cb, connect_cb);
+
+	return io;
+}
+
 size_t gatt_attr_data_from_string(const char *str, uint8_t **data)
 {
 	char tmp[3];
-- 
1.8.3.1


^ permalink raw reply related

* [RFC BlueZ v0 14/17] test: Add registering external service
From: Claudio Takahasi @ 2013-11-27 20:50 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1385585457-26951-1-git-send-email-claudio.takahasi@openbossa.org>

This patch extends gatt-service to call RegisterService() when org.bluez
service gets connected to the system bus.
---
 test/gatt-service.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 66 insertions(+)

diff --git a/test/gatt-service.c b/test/gatt-service.c
index 06719b4..c26a5be 100644
--- a/test/gatt-service.c
+++ b/test/gatt-service.c
@@ -114,6 +114,65 @@ static void create_services(DBusConnection *conn)
 	printf("Registered service: %s\n", service_path);
 }
 
+static void register_external_service_reply(DBusPendingCall *call,
+							void *user_data)
+{
+	DBusMessage *reply = dbus_pending_call_steal_reply(call);
+	DBusError derr;
+
+	dbus_error_init(&derr);
+	dbus_set_error_from_message(&derr, reply);
+
+	if (dbus_error_is_set(&derr))
+		fprintf(stderr, "RegisterService: %s\n", derr.message);
+	else
+		printf("RegisterService: OK\n");
+
+	dbus_message_unref(reply);
+	dbus_error_free(&derr);
+}
+
+static void register_external_service(gpointer a, gpointer b)
+{
+	DBusConnection *conn = b;
+	const char *path = a;
+	DBusMessage *msg;
+	DBusPendingCall *call;
+	DBusMessageIter iter, dict;
+
+	msg = dbus_message_new_method_call("org.bluez", "/org/bluez",
+					SERVICE_MGR_IFACE, "RegisterService");
+	if (msg == NULL) {
+		fprintf(stderr, "Couldn't allocate D-Bus message\n");
+		return;
+	}
+
+	dbus_message_iter_init_append(msg, &iter);
+
+	dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH, &path);
+
+	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "{sv}", &dict);
+
+	/* TODO: Add options dictionary */
+
+	dbus_message_iter_close_container(&iter, &dict);
+
+	if (g_dbus_send_message_with_reply(conn, msg, &call, -1) == FALSE) {
+		dbus_message_unref(msg);
+		return;
+	}
+
+	dbus_pending_call_set_notify(call, register_external_service_reply,
+								NULL, NULL);
+
+	dbus_pending_call_unref(call);
+}
+
+static void connect_handler(DBusConnection *conn, void *user_data)
+{
+	g_slist_foreach(services, register_external_service, conn);
+}
+
 static gboolean signal_handler(GIOChannel *channel, GIOCondition condition,
 							gpointer user_data)
 {
@@ -159,6 +218,7 @@ static guint setup_signalfd(void)
 
 int main(int argc, char *argv[])
 {
+	GDBusClient *client;
 	DBusConnection *dbus_conn;
 	guint signal;
 
@@ -177,8 +237,14 @@ int main(int argc, char *argv[])
 
 	create_services(dbus_conn);
 
+	client = g_dbus_client_new(dbus_conn, "org.bluez", "/org/bluez");
+
+	g_dbus_client_set_connect_watch(client, connect_handler, NULL);
+
 	g_main_loop_run(main_loop);
 
+	g_dbus_client_unref(client);
+
 	g_source_remove(signal);
 
 	g_slist_free_full(services, g_free);
-- 
1.8.3.1


^ permalink raw reply related


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