Linux bluetooth development
 help / color / mirror / Atom feed
* [PATCH] android/a2dp: Fix audio resume on started stream
From: Andrzej Kaczmarek @ 2014-01-23 16:59 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Andrzej Kaczmarek

In case stream is started from remote we'll receive Resume Stream IPC
when audio is already considered as started (i.e. on first write from
AudioFlinger). In such case we should not try to send AVDTP_START since
this will fail but just reply success over IPC instead.
---
 android/a2dp.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/android/a2dp.c b/android/a2dp.c
index 572e0d1..10e43b1 100644
--- a/android/a2dp.c
+++ b/android/a2dp.c
@@ -1376,10 +1376,12 @@ static void bt_stream_resume(const void *buf, uint16_t len)
 		goto failed;
 	}
 
-	err = avdtp_start(setup->dev->session, setup->stream);
-	if (err < 0) {
-		error("avdtp_start: %s", strerror(-err));
-		goto failed;
+	if (setup->state != HAL_AUDIO_STARTED) {
+		err = avdtp_start(setup->dev->session, setup->stream);
+		if (err < 0) {
+			error("avdtp_start: %s", strerror(-err));
+			goto failed;
+		}
 	}
 
 	audio_ipc_send_rsp(AUDIO_OP_RESUME_STREAM, AUDIO_STATUS_SUCCESS);
-- 
1.8.5.2


^ permalink raw reply related

* [PATCH 10/10] android/tester: Add remove bond bad addr dev test case
From: Grzegorz Kolodziejczyk @ 2014-01-23 16:57 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1390496258-5480-1-git-send-email-grzegorz.kolodziejczyk@tieto.com>

This adds remove bond fail test case. Bad addres is given as a parametr
for remove bond hal function.
---
 android/android-tester.c | 35 +++++++++++++++++++++++++++++++++++
 1 file changed, 35 insertions(+)

diff --git a/android/android-tester.c b/android/android-tester.c
index 86a76d1..2272416 100644
--- a/android/android-tester.c
+++ b/android/android-tester.c
@@ -953,6 +953,15 @@ static void bond_remove_success_state_changed_cb(bt_status_t status,
 	}
 }
 
+static void bond_remove_bad_addr_state_changed_cb(bt_status_t status,
+			bt_bdaddr_t *remote_bd_addr, bt_bond_state_t state)
+{
+	struct test_data *data = tester_get_data();
+
+	if (state == BT_BOND_STATE_NONE)
+		data->cb_count--;
+}
+
 static void bond_state_changed_cb(bt_status_t status,
 			bt_bdaddr_t *remote_bd_addr, bt_bond_state_t state)
 {
@@ -2181,6 +2190,13 @@ static const struct generic_data bt_bond_remove_success_test = {
 	.expected_adapter_status = BT_STATUS_SUCCESS,
 };
 
+static const struct generic_data bt_bond_remove_bad_addr_test = {
+	.expected_hal_cb.bond_state_changed_cb =
+					bond_remove_bad_addr_state_changed_cb,
+	.expected_cb_count = 1,
+	.expected_adapter_status = BT_STATUS_SUCCESS,
+};
+
 static bt_callbacks_t bt_callbacks = {
 	.size = sizeof(bt_callbacks),
 	.adapter_state_changed_cb = adapter_state_changed_cb,
@@ -3105,6 +3121,20 @@ static void test_bond_remove_success(const void *test_data)
 	data->if_bluetooth->start_discovery();
 }
 
+static void test_bond_remove_bad_addr(const void *test_data)
+{
+	struct test_data *data = tester_get_data();
+	bt_status_t status;
+	bt_bdaddr_t bad_addr = {
+		.address = { 0x12, 0x34, 0x56, 0x78, 0x90, 0x12 }
+	};
+
+	init_test_conditions(data);
+
+	status = data->if_bluetooth->remove_bond(&bad_addr);
+	check_expected_status(status);
+}
+
 /* Test Socket HAL */
 
 static void adapter_socket_state_changed_cb(bt_state_t state)
@@ -4277,6 +4307,11 @@ int main(int argc, char *argv[])
 					setup_enabled_adapter,
 					test_bond_remove_success, teardown);
 
+	test_bredrle("Bluetooth Remove Bond - Bad Address",
+					&bt_bond_remove_bad_addr_test,
+					setup_enabled_adapter,
+					test_bond_remove_bad_addr, teardown);
+
 	test_bredrle("Socket Init", NULL, setup_socket_interface,
 						test_dummy, teardown);
 
-- 
1.8.5.2


^ permalink raw reply related

* [PATCH 09/10] android/tester: Add remove bond success test case
From: Grzegorz Kolodziejczyk @ 2014-01-23 16:57 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1390496258-5480-1-git-send-email-grzegorz.kolodziejczyk@tieto.com>

This adds remove bond success test case. SSP as pairing mode.
---
 android/android-tester.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 51 insertions(+)

diff --git a/android/android-tester.c b/android/android-tester.c
index ee5f225..86a76d1 100644
--- a/android/android-tester.c
+++ b/android/android-tester.c
@@ -930,6 +930,29 @@ static void bond_test_state_changed_cb(bt_status_t status,
 	}
 }
 
+static void bond_remove_success_state_changed_cb(bt_status_t status,
+			bt_bdaddr_t *remote_bd_addr, bt_bond_state_t state)
+{
+	struct test_data *data = tester_get_data();
+	bt_status_t remove_status;
+	uint8_t *bdaddr = (uint8_t *)hciemu_get_client_bdaddr(data->hciemu);
+	bt_bdaddr_t remote_addr;
+
+	bdaddr2android((const bdaddr_t *)bdaddr, &remote_addr.address);
+
+	if (state == BT_BOND_STATE_BONDED) {
+		data->cb_count--;
+		remove_status = data->if_bluetooth->remove_bond(&remote_addr);
+		check_expected_status(remove_status);
+		return;
+	}
+
+	if (state == BT_BOND_STATE_NONE) {
+		data->cb_count--;
+		check_cb_count();
+	}
+}
+
 static void bond_state_changed_cb(bt_status_t status,
 			bt_bdaddr_t *remote_bd_addr, bt_bond_state_t state)
 {
@@ -2150,6 +2173,14 @@ static const struct generic_data bt_bond_cancel_success_test = {
 	.expected_adapter_status = BT_STATUS_SUCCESS,
 };
 
+static const struct generic_data bt_bond_remove_success_test = {
+	.expected_hal_cb.bond_state_changed_cb =
+					bond_remove_success_state_changed_cb,
+	.expected_hal_cb.ssp_request_cb = bond_create_ssp_success_request_cb,
+	.expected_cb_count = 4,
+	.expected_adapter_status = BT_STATUS_SUCCESS,
+};
+
 static bt_callbacks_t bt_callbacks = {
 	.size = sizeof(bt_callbacks),
 	.adapter_state_changed_cb = adapter_state_changed_cb,
@@ -3059,6 +3090,21 @@ static void test_bond_cancel_success(const void *test_data)
 	data->if_bluetooth->start_discovery();
 }
 
+static void test_bond_remove_success(const void *test_data)
+{
+	struct test_data *data = tester_get_data();
+	struct bthost *bthost = hciemu_client_get_host(data->hciemu);
+
+	init_test_conditions(data);
+
+	mgmt_register(data->mgmt, MGMT_EV_DEVICE_FOUND, data->mgmt_index,
+			bond_device_nostatus_found_callback, data, NULL);
+
+	bthost_write_ssp_mode(bthost, 0x01);
+
+	data->if_bluetooth->start_discovery();
+}
+
 /* Test Socket HAL */
 
 static void adapter_socket_state_changed_cb(bt_state_t state)
@@ -4226,6 +4272,11 @@ int main(int argc, char *argv[])
 					setup_enabled_adapter,
 					test_bond_cancel_success, teardown);
 
+	test_bredrle("Bluetooth Remove Bond - Success",
+					&bt_bond_remove_success_test,
+					setup_enabled_adapter,
+					test_bond_remove_success, teardown);
+
 	test_bredrle("Socket Init", NULL, setup_socket_interface,
 						test_dummy, teardown);
 
-- 
1.8.5.2


^ permalink raw reply related

* [PATCH 08/10] android/tester: Add cancel bond success test case
From: Grzegorz Kolodziejczyk @ 2014-01-23 16:57 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1390496258-5480-1-git-send-email-grzegorz.kolodziejczyk@tieto.com>

This adds cancel bond success test case. SSP as pairing mode.
---
 android/android-tester.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 45 insertions(+)

diff --git a/android/android-tester.c b/android/android-tester.c
index 3268904..ee5f225 100644
--- a/android/android-tester.c
+++ b/android/android-tester.c
@@ -1050,6 +1050,24 @@ static void bond_create_ssp_fail_request_cb(bt_bdaddr_t *remote_bd_addr,
 	bond_create_ssp_request_cb(remote_bd_addr, pairing_variant, accept);
 }
 
+static void bond_cancel_success_ssp_request_cb(bt_bdaddr_t *remote_bd_addr,
+					bt_bdname_t *bd_name, uint32_t cod,
+					bt_ssp_variant_t pairing_variant,
+					uint32_t pass_key)
+{
+	struct test_data *data = tester_get_data();
+	uint8_t *bdaddr = (uint8_t *)hciemu_get_client_bdaddr(data->hciemu);
+	bt_bdaddr_t remote_addr;
+	bt_status_t status;
+
+	bdaddr2android((const bdaddr_t *)bdaddr, &remote_addr.address);
+
+	data->cb_count--;
+
+	status = data->if_bluetooth->cancel_bond(&remote_addr);
+	check_expected_status(status);
+}
+
 static void ssp_request_cb(bt_bdaddr_t *remote_bd_addr, bt_bdname_t *bd_name,
 				uint32_t cod, bt_ssp_variant_t pairing_variant,
 				uint32_t pass_key)
@@ -2125,6 +2143,13 @@ static const struct generic_data bt_bond_create_bad_addr_success_test = {
 	.expected_adapter_status = MGMT_STATUS_CONNECT_FAILED,
 };
 
+static const struct generic_data bt_bond_cancel_success_test = {
+	.expected_hal_cb.bond_state_changed_cb = bond_test_state_changed_cb,
+	.expected_hal_cb.ssp_request_cb = bond_cancel_success_ssp_request_cb,
+	.expected_cb_count = 4,
+	.expected_adapter_status = BT_STATUS_SUCCESS,
+};
+
 static bt_callbacks_t bt_callbacks = {
 	.size = sizeof(bt_callbacks),
 	.adapter_state_changed_cb = adapter_state_changed_cb,
@@ -3019,6 +3044,21 @@ static void test_bond_create_bad_addr_success(const void *test_data)
 	data->if_bluetooth->create_bond(&bad_addr);
 }
 
+static void test_bond_cancel_success(const void *test_data)
+{
+	struct test_data *data = tester_get_data();
+	struct bthost *bthost = hciemu_client_get_host(data->hciemu);
+
+	init_test_conditions(data);
+
+	mgmt_register(data->mgmt, MGMT_EV_DEVICE_FOUND, data->mgmt_index,
+			bond_device_nostatus_found_callback, data, NULL);
+
+	bthost_write_ssp_mode(bthost, 0x01);
+
+	data->if_bluetooth->start_discovery();
+}
+
 /* Test Socket HAL */
 
 static void adapter_socket_state_changed_cb(bt_state_t state)
@@ -4181,6 +4221,11 @@ int main(int argc, char *argv[])
 				setup_enabled_adapter,
 				test_bond_create_bad_addr_success, teardown);
 
+	test_bredrle("Bluetooth Cancel Bonding - Success",
+					&bt_bond_cancel_success_test,
+					setup_enabled_adapter,
+					test_bond_cancel_success, teardown);
+
 	test_bredrle("Socket Init", NULL, setup_socket_interface,
 						test_dummy, teardown);
 
-- 
1.8.5.2


^ permalink raw reply related

* [PATCH 07/10] android/tester: Add create bond with bad addr fail test case
From: Grzegorz Kolodziejczyk @ 2014-01-23 16:57 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1390496258-5480-1-git-send-email-grzegorz.kolodziejczyk@tieto.com>

This adds create bond with bad addr fail test case.
---
 android/android-tester.c | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/android/android-tester.c b/android/android-tester.c
index f31bf0f..3268904 100644
--- a/android/android-tester.c
+++ b/android/android-tester.c
@@ -2121,6 +2121,10 @@ static const struct generic_data bt_bond_create_no_disc_success_test = {
 	.expected_adapter_status = BT_STATUS_SUCCESS,
 };
 
+static const struct generic_data bt_bond_create_bad_addr_success_test = {
+	.expected_adapter_status = MGMT_STATUS_CONNECT_FAILED,
+};
+
 static bt_callbacks_t bt_callbacks = {
 	.size = sizeof(bt_callbacks),
 	.adapter_state_changed_cb = adapter_state_changed_cb,
@@ -2999,6 +3003,22 @@ static void test_bond_create_no_disc_success(const void *test_data)
 	check_expected_status(status);
 }
 
+static void test_bond_create_bad_addr_success(const void *test_data)
+{
+	struct test_data *data = tester_get_data();
+	bt_bdaddr_t bad_addr = {
+		.address = { 0x12, 0x34, 0x56, 0x78, 0x90, 0x12 }
+	};
+
+	init_test_conditions(data);
+
+	mgmt_register(data->mgmt, MGMT_EV_CONNECT_FAILED, data->mgmt_index,
+					bond_device_auth_fail_callback, data,
+					NULL);
+
+	data->if_bluetooth->create_bond(&bad_addr);
+}
+
 /* Test Socket HAL */
 
 static void adapter_socket_state_changed_cb(bt_state_t state)
@@ -4156,6 +4176,11 @@ int main(int argc, char *argv[])
 				setup_enabled_adapter,
 				test_bond_create_no_disc_success, teardown);
 
+	test_bredrle("Bluetooth Create Bond - Bad Address",
+				&bt_bond_create_bad_addr_success_test,
+				setup_enabled_adapter,
+				test_bond_create_bad_addr_success, teardown);
+
 	test_bredrle("Socket Init", NULL, setup_socket_interface,
 						test_dummy, teardown);
 
-- 
1.8.5.2


^ permalink raw reply related

* [PATCH 06/10] android/tester: Add create bond with no discovery test case
From: Grzegorz Kolodziejczyk @ 2014-01-23 16:57 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1390496258-5480-1-git-send-email-grzegorz.kolodziejczyk@tieto.com>

This adds create bond with no discovery before create bond as NFC does.
SSP with confirm as authentication mode.
---
 android/android-tester.c | 31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/android/android-tester.c b/android/android-tester.c
index 0d37fb3..f31bf0f 100644
--- a/android/android-tester.c
+++ b/android/android-tester.c
@@ -2114,6 +2114,13 @@ static const struct generic_data bt_bond_create_ssp_fail_test = {
 	.expected_adapter_status = MGMT_STATUS_AUTH_FAILED,
 };
 
+static const struct generic_data bt_bond_create_no_disc_success_test = {
+	.expected_hal_cb.bond_state_changed_cb = bond_test_state_changed_cb,
+	.expected_hal_cb.ssp_request_cb = bond_create_ssp_success_request_cb,
+	.expected_cb_count = 3,
+	.expected_adapter_status = BT_STATUS_SUCCESS,
+};
+
 static bt_callbacks_t bt_callbacks = {
 	.size = sizeof(bt_callbacks),
 	.adapter_state_changed_cb = adapter_state_changed_cb,
@@ -2973,6 +2980,25 @@ static void test_bond_create_ssp_fail(const void *test_data)
 	data->if_bluetooth->start_discovery();
 }
 
+static void test_bond_create_no_disc_success(const void *test_data)
+{
+	struct test_data *data = tester_get_data();
+	struct bthost *bthost = hciemu_client_get_host(data->hciemu);
+
+	uint8_t *bdaddr = (uint8_t *)hciemu_get_client_bdaddr(data->hciemu);
+	bt_bdaddr_t remote_addr;
+	bt_status_t status;
+
+	init_test_conditions(data);
+
+	bdaddr2android((const bdaddr_t *)bdaddr, &remote_addr.address);
+
+	bthost_write_ssp_mode(bthost, 0x01);
+
+	status = data->if_bluetooth->create_bond(&remote_addr);
+	check_expected_status(status);
+}
+
 /* Test Socket HAL */
 
 static void adapter_socket_state_changed_cb(bt_state_t state)
@@ -4125,6 +4151,11 @@ int main(int argc, char *argv[])
 					setup_enabled_adapter,
 					test_bond_create_ssp_fail, teardown);
 
+	test_bredrle("Bluetooth Create Bond - No Discovery",
+				&bt_bond_create_no_disc_success_test,
+				setup_enabled_adapter,
+				test_bond_create_no_disc_success, teardown);
+
 	test_bredrle("Socket Init", NULL, setup_socket_interface,
 						test_dummy, teardown);
 
-- 
1.8.5.2


^ permalink raw reply related

* [PATCH 05/10] android/tester: Add create bond with SSP fail test case
From: Grzegorz Kolodziejczyk @ 2014-01-23 16:57 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1390496258-5480-1-git-send-email-grzegorz.kolodziejczyk@tieto.com>

This adds create bond with SSP fail test case. Confirm is set as SSP
pairing mode.
---
 android/android-tester.c | 41 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 41 insertions(+)

diff --git a/android/android-tester.c b/android/android-tester.c
index 1ee1196..0d37fb3 100644
--- a/android/android-tester.c
+++ b/android/android-tester.c
@@ -1040,6 +1040,16 @@ static void bond_create_ssp_success_request_cb(bt_bdaddr_t *remote_bd_addr,
 	bond_create_ssp_request_cb(remote_bd_addr, pairing_variant, accept);
 }
 
+static void bond_create_ssp_fail_request_cb(bt_bdaddr_t *remote_bd_addr,
+					bt_bdname_t *bd_name, uint32_t cod,
+					bt_ssp_variant_t pairing_variant,
+					uint32_t pass_key)
+{
+	bool accept = false;
+
+	bond_create_ssp_request_cb(remote_bd_addr, pairing_variant, accept);
+}
+
 static void ssp_request_cb(bt_bdaddr_t *remote_bd_addr, bt_bdname_t *bd_name,
 				uint32_t cod, bt_ssp_variant_t pairing_variant,
 				uint32_t pass_key)
@@ -2097,6 +2107,13 @@ static const struct generic_data bt_bond_create_ssp_success_test = {
 	.expected_adapter_status = BT_STATUS_SUCCESS,
 };
 
+static const struct generic_data bt_bond_create_ssp_fail_test = {
+	.expected_hal_cb.bond_state_changed_cb = bond_test_state_changed_cb,
+	.expected_hal_cb.ssp_request_cb = bond_create_ssp_fail_request_cb,
+	.expected_cb_count = 4,
+	.expected_adapter_status = MGMT_STATUS_AUTH_FAILED,
+};
+
 static bt_callbacks_t bt_callbacks = {
 	.size = sizeof(bt_callbacks),
 	.adapter_state_changed_cb = adapter_state_changed_cb,
@@ -2937,6 +2954,25 @@ static void test_bond_create_ssp_success(const void *test_data)
 	data->if_bluetooth->start_discovery();
 }
 
+static void test_bond_create_ssp_fail(const void *test_data)
+{
+	struct test_data *data = tester_get_data();
+	struct bthost *bthost = hciemu_client_get_host(data->hciemu);
+
+	init_test_conditions(data);
+
+	mgmt_register(data->mgmt, MGMT_EV_DEVICE_FOUND, data->mgmt_index,
+					bond_device_nostatus_found_callback,
+					data, NULL);
+	mgmt_register(data->mgmt, MGMT_EV_AUTH_FAILED, data->mgmt_index,
+					bond_device_auth_fail_callback, data,
+					NULL);
+
+	bthost_write_ssp_mode(bthost, 0x01);
+
+	data->if_bluetooth->start_discovery();
+}
+
 /* Test Socket HAL */
 
 static void adapter_socket_state_changed_cb(bt_state_t state)
@@ -4084,6 +4120,11 @@ int main(int argc, char *argv[])
 					setup_enabled_adapter,
 					test_bond_create_ssp_success, teardown);
 
+	test_bredrle("Bluetooth Create Bond SSP - Negative reply",
+					&bt_bond_create_ssp_fail_test,
+					setup_enabled_adapter,
+					test_bond_create_ssp_fail, teardown);
+
 	test_bredrle("Socket Init", NULL, setup_socket_interface,
 						test_dummy, teardown);
 
-- 
1.8.5.2


^ permalink raw reply related

* [PATCH 04/10] android/tester: Add create bond with SSP sucess test case
From: Grzegorz Kolodziejczyk @ 2014-01-23 16:57 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1390496258-5480-1-git-send-email-grzegorz.kolodziejczyk@tieto.com>

This adds create bond with SSP succes test case. Confirm is set as SSP
pairing mode.
---
 android/android-tester.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 80 insertions(+), 1 deletion(-)

diff --git a/android/android-tester.c b/android/android-tester.c
index defab30..1ee1196 100644
--- a/android/android-tester.c
+++ b/android/android-tester.c
@@ -1002,6 +1002,58 @@ static void pin_request_cb(bt_bdaddr_t *remote_bd_addr,
 									cod);
 }
 
+static void bond_create_ssp_request_cb(const bt_bdaddr_t *remote_bd_addr,
+					bt_ssp_variant_t pairing_variant,
+					bool accept)
+{
+	bdaddr_t remote_addr;
+	struct test_data *data = tester_get_data();
+	struct mgmt_addr_info cp;
+	uint16_t opcode;
+
+	android2bdaddr(remote_bd_addr, &remote_addr);
+
+	if (pairing_variant == 0) {	/* HAL_SSP_VARIANT_CONFIRM */
+		if (accept)
+			opcode = MGMT_OP_USER_CONFIRM_REPLY;
+		else
+			opcode = MGMT_OP_USER_CONFIRM_NEG_REPLY;
+
+		data->cb_count--;
+
+		bacpy(&cp.bdaddr, &remote_addr);
+		cp.type = BDADDR_BREDR;
+
+		mgmt_reply(data->mgmt, opcode, data->mgmt_index, sizeof(cp),
+							&cp, NULL, NULL, NULL);
+	} else
+		tester_test_failed();
+}
+
+static void bond_create_ssp_success_request_cb(bt_bdaddr_t *remote_bd_addr,
+					bt_bdname_t *bd_name, uint32_t cod,
+					bt_ssp_variant_t pairing_variant,
+					uint32_t pass_key)
+{
+	bool accept = true;
+
+	bond_create_ssp_request_cb(remote_bd_addr, pairing_variant, accept);
+}
+
+static void ssp_request_cb(bt_bdaddr_t *remote_bd_addr, bt_bdname_t *bd_name,
+				uint32_t cod, bt_ssp_variant_t pairing_variant,
+				uint32_t pass_key)
+{
+	struct test_data *data = tester_get_data();
+	const struct generic_data *test = data->test_data;
+
+	if (data->test_init_done &&
+				test->expected_hal_cb.ssp_request_cb) {
+		test->expected_hal_cb.ssp_request_cb(remote_bd_addr, bd_name,
+					cod, pairing_variant, pass_key);
+	}
+}
+
 static bt_bdaddr_t enable_done_bdaddr_val = { {0x00} };
 static char enable_done_bdname_val[] = "BlueZ for Android";
 static bt_uuid_t enable_done_uuids_val = {
@@ -2038,6 +2090,13 @@ static const struct generic_data bt_bond_create_pin_fail_test = {
 	.expected_adapter_status = MGMT_STATUS_AUTH_FAILED,
 };
 
+static const struct generic_data bt_bond_create_ssp_success_test = {
+	.expected_hal_cb.bond_state_changed_cb = bond_test_state_changed_cb,
+	.expected_hal_cb.ssp_request_cb = bond_create_ssp_success_request_cb,
+	.expected_cb_count = 4,
+	.expected_adapter_status = BT_STATUS_SUCCESS,
+};
+
 static bt_callbacks_t bt_callbacks = {
 	.size = sizeof(bt_callbacks),
 	.adapter_state_changed_cb = adapter_state_changed_cb,
@@ -2046,7 +2105,7 @@ static bt_callbacks_t bt_callbacks = {
 	.device_found_cb = device_found_cb,
 	.discovery_state_changed_cb = discovery_state_changed_cb,
 	.pin_request_cb = pin_request_cb,
-	.ssp_request_cb = NULL,
+	.ssp_request_cb = ssp_request_cb,
 	.bond_state_changed_cb = bond_state_changed_cb,
 	.acl_state_changed_cb = NULL,
 	.thread_evt_cb = NULL,
@@ -2863,6 +2922,21 @@ static void test_bond_create_pin_fail(const void *test_data)
 	data->if_bluetooth->start_discovery();
 }
 
+static void test_bond_create_ssp_success(const void *test_data)
+{
+	struct test_data *data = tester_get_data();
+	struct bthost *bthost = hciemu_client_get_host(data->hciemu);
+
+	init_test_conditions(data);
+
+	mgmt_register(data->mgmt, MGMT_EV_DEVICE_FOUND, data->mgmt_index,
+					bond_device_found_callback, data, NULL);
+
+	bthost_write_ssp_mode(bthost, 0x01);
+
+	data->if_bluetooth->start_discovery();
+}
+
 /* Test Socket HAL */
 
 static void adapter_socket_state_changed_cb(bt_state_t state)
@@ -4005,6 +4079,11 @@ int main(int argc, char *argv[])
 					setup_enabled_adapter,
 					test_bond_create_pin_fail, teardown);
 
+	test_bredrle("Bluetooth Create Bond SSP - Success",
+					&bt_bond_create_ssp_success_test,
+					setup_enabled_adapter,
+					test_bond_create_ssp_success, teardown);
+
 	test_bredrle("Socket Init", NULL, setup_socket_interface,
 						test_dummy, teardown);
 
-- 
1.8.5.2


^ permalink raw reply related

* [PATCH 03/10] android/tester: Add create bond with PIN fail test case
From: Grzegorz Kolodziejczyk @ 2014-01-23 16:57 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1390496258-5480-1-git-send-email-grzegorz.kolodziejczyk@tieto.com>

This adds create bond with PIN fail test case.
---
 android/android-tester.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 85 insertions(+)

diff --git a/android/android-tester.c b/android/android-tester.c
index a3973af..defab30 100644
--- a/android/android-tester.c
+++ b/android/android-tester.c
@@ -966,6 +966,31 @@ static void bond_create_pin_success_request_cb(bt_bdaddr_t *remote_bd_addr,
 					sizeof(rp), &rp, NULL, NULL, NULL);
 }
 
+static void bond_create_pin_fail_request_cb(bt_bdaddr_t *remote_bd_addr,
+					bt_bdname_t *bd_name, uint32_t cod)
+{
+	struct test_data *data = tester_get_data();
+	struct mgmt_cp_pin_code_reply rp;
+	bdaddr_t remote_addr;
+	static uint8_t bad_device_pin[] = { 0x31, 0x31, 0x31, 0x31 };
+	const void *pin_code = bad_device_pin;
+	uint8_t pin_len = 4;
+
+	memset(&rp, 0, sizeof(rp));
+
+	android2bdaddr(remote_bd_addr, &remote_addr);
+
+	data->cb_count--;
+
+	bacpy(&rp.addr.bdaddr, &remote_addr);
+	rp.addr.type = BDADDR_BREDR;
+	rp.pin_len = pin_len;
+	memcpy(rp.pin_code, pin_code, rp.pin_len);
+
+	mgmt_reply(data->mgmt, MGMT_OP_PIN_CODE_REPLY, data->mgmt_index,
+					sizeof(rp), &rp, NULL, NULL, NULL);
+}
+
 static void pin_request_cb(bt_bdaddr_t *remote_bd_addr,
 					bt_bdname_t *bd_name, uint32_t cod)
 {
@@ -2006,6 +2031,13 @@ static const struct generic_data bt_bond_create_pin_success_test = {
 	.expected_adapter_status = BT_STATUS_SUCCESS,
 };
 
+static const struct generic_data bt_bond_create_pin_fail_test = {
+	.expected_hal_cb.bond_state_changed_cb = bond_test_state_changed_cb,
+	.expected_hal_cb.pin_request_cb = bond_create_pin_fail_request_cb,
+	.expected_cb_count = 4,
+	.expected_adapter_status = MGMT_STATUS_AUTH_FAILED,
+};
+
 static bt_callbacks_t bt_callbacks = {
 	.size = sizeof(bt_callbacks),
 	.adapter_state_changed_cb = adapter_state_changed_cb,
@@ -2764,6 +2796,31 @@ static void bond_device_found_callback(uint16_t index, uint16_t length,
 	}
 }
 
+static void bond_device_nostatus_found_callback(uint16_t index, uint16_t length,
+							const void *param,
+							void *user_data)
+{
+	struct test_data *data = tester_get_data();
+	uint8_t *bdaddr = (uint8_t *)hciemu_get_client_bdaddr(data->hciemu);
+	bt_bdaddr_t remote_addr;
+
+	bdaddr2android((const bdaddr_t *)bdaddr, &remote_addr.address);
+
+	if (data->cb_count == 4) {
+		data->cb_count--;
+		data->if_bluetooth->create_bond(&remote_addr);
+	}
+}
+
+static void bond_device_auth_fail_callback(uint16_t index, uint16_t length,
+							const void *param,
+							void *user_data)
+{
+	const struct mgmt_ev_auth_failed *ev = param;
+
+	check_expected_status(ev->status);
+}
+
 static void test_bond_create_pin_success(const void *test_data)
 {
 	struct test_data *data = tester_get_data();
@@ -2783,6 +2840,29 @@ static void test_bond_create_pin_success(const void *test_data)
 	data->if_bluetooth->start_discovery();
 }
 
+static void test_bond_create_pin_fail(const void *test_data)
+{
+	struct test_data *data = tester_get_data();
+	struct bthost *bthost = hciemu_client_get_host(data->hciemu);
+
+	static uint8_t pair_device_pin[] = { 0x30, 0x30, 0x30, 0x30 };
+	const void *pin = pair_device_pin;
+	uint8_t pin_len = 4;
+
+	init_test_conditions(data);
+
+	mgmt_register(data->mgmt, MGMT_EV_DEVICE_FOUND, data->mgmt_index,
+					bond_device_nostatus_found_callback,
+					data, NULL);
+	mgmt_register(data->mgmt, MGMT_EV_AUTH_FAILED, data->mgmt_index,
+					bond_device_auth_fail_callback, data,
+					NULL);
+
+	bthost_set_pin_code(bthost, pin, pin_len);
+
+	data->if_bluetooth->start_discovery();
+}
+
 /* Test Socket HAL */
 
 static void adapter_socket_state_changed_cb(bt_state_t state)
@@ -3920,6 +4000,11 @@ int main(int argc, char *argv[])
 					setup_enabled_adapter,
 					test_bond_create_pin_success, teardown);
 
+	test_bredrle("Bluetooth Create Bond PIN - Bad PIN",
+					&bt_bond_create_pin_fail_test,
+					setup_enabled_adapter,
+					test_bond_create_pin_fail, teardown);
+
 	test_bredrle("Socket Init", NULL, setup_socket_interface,
 						test_dummy, teardown);
 
-- 
1.8.5.2


^ permalink raw reply related

* [PATCH 02/10] android/tester: Add create bond with PIN success test case
From: Grzegorz Kolodziejczyk @ 2014-01-23 16:57 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1390496258-5480-1-git-send-email-grzegorz.kolodziejczyk@tieto.com>

This adds create bond with PIN success test case.
---
 android/android-tester.c | 123 ++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 121 insertions(+), 2 deletions(-)

diff --git a/android/android-tester.c b/android/android-tester.c
index 4bd48d6..a3973af 100644
--- a/android/android-tester.c
+++ b/android/android-tester.c
@@ -908,6 +908,75 @@ static void remote_device_properties_cb(bt_status_t status,
 					bd_addr, num_properties, properties);
 }
 
+static void bond_test_state_changed_cb(bt_status_t status,
+			bt_bdaddr_t *remote_bd_addr, bt_bond_state_t state)
+{
+	struct test_data *data = tester_get_data();
+
+	switch (state) {
+	case BT_BOND_STATE_NONE:
+		data->cb_count--;
+		check_cb_count();
+		break;
+	case BT_BOND_STATE_BONDING:
+		data->cb_count--;
+		break;
+	case BT_BOND_STATE_BONDED:
+		data->cb_count--;
+		check_cb_count();
+		break;
+	default:
+		break;
+	}
+}
+
+static void bond_state_changed_cb(bt_status_t status,
+			bt_bdaddr_t *remote_bd_addr, bt_bond_state_t state)
+{
+	struct test_data *data = tester_get_data();
+	const struct generic_data *test = data->test_data;
+
+	if (data->test_init_done && test->expected_hal_cb.bond_state_changed_cb)
+			test->expected_hal_cb.bond_state_changed_cb(status,
+							remote_bd_addr, state);
+}
+
+static void bond_create_pin_success_request_cb(bt_bdaddr_t *remote_bd_addr,
+					bt_bdname_t *bd_name, uint32_t cod)
+{
+	struct test_data *data = tester_get_data();
+	struct mgmt_cp_pin_code_reply rp;
+	bdaddr_t remote_addr;
+	static uint8_t pair_device_pin[] = { 0x30, 0x30, 0x30, 0x30 };
+	const void *pin_code = pair_device_pin;
+	uint8_t pin_len = 4;
+
+	memset(&rp, 0, sizeof(rp));
+
+	data->cb_count--;
+
+	android2bdaddr(remote_bd_addr, &remote_addr);
+
+	bacpy(&rp.addr.bdaddr, &remote_addr);
+	rp.addr.type = BDADDR_BREDR;
+	rp.pin_len = pin_len;
+	memcpy(rp.pin_code, pin_code, rp.pin_len);
+
+	mgmt_reply(data->mgmt, MGMT_OP_PIN_CODE_REPLY, data->mgmt_index,
+					sizeof(rp), &rp, NULL, NULL, NULL);
+}
+
+static void pin_request_cb(bt_bdaddr_t *remote_bd_addr,
+					bt_bdname_t *bd_name, uint32_t cod)
+{
+	struct test_data *data = tester_get_data();
+	const struct generic_data *test = data->test_data;
+
+	if (data->test_init_done && test->expected_hal_cb.pin_request_cb)
+		test->expected_hal_cb.pin_request_cb(remote_bd_addr, bd_name,
+									cod);
+}
+
 static bt_bdaddr_t enable_done_bdaddr_val = { {0x00} };
 static char enable_done_bdname_val[] = "BlueZ for Android";
 static bt_uuid_t enable_done_uuids_val = {
@@ -1930,6 +1999,13 @@ static const struct generic_data bt_dev_setprop_disctimeout_fail_test = {
 	.expected_adapter_status = BT_STATUS_FAIL,
 };
 
+static const struct generic_data bt_bond_create_pin_success_test = {
+	.expected_hal_cb.bond_state_changed_cb = bond_test_state_changed_cb,
+	.expected_hal_cb.pin_request_cb = bond_create_pin_success_request_cb,
+	.expected_cb_count = 4,
+	.expected_adapter_status = BT_STATUS_SUCCESS,
+};
+
 static bt_callbacks_t bt_callbacks = {
 	.size = sizeof(bt_callbacks),
 	.adapter_state_changed_cb = adapter_state_changed_cb,
@@ -1937,9 +2013,9 @@ static bt_callbacks_t bt_callbacks = {
 	.remote_device_properties_cb = remote_device_properties_cb,
 	.device_found_cb = device_found_cb,
 	.discovery_state_changed_cb = discovery_state_changed_cb,
-	.pin_request_cb = NULL,
+	.pin_request_cb = pin_request_cb,
 	.ssp_request_cb = NULL,
-	.bond_state_changed_cb = NULL,
+	.bond_state_changed_cb = bond_state_changed_cb,
 	.acl_state_changed_cb = NULL,
 	.thread_evt_cb = NULL,
 	.dut_mode_recv_cb = NULL,
@@ -2669,6 +2745,44 @@ static void test_dev_setprop_disctimeout_fail(const void *test_data)
 
 	data->if_bluetooth->start_discovery();
 }
+
+static void bond_device_found_callback(uint16_t index, uint16_t length,
+							const void *param,
+							void *user_data)
+{
+	struct test_data *data = tester_get_data();
+	uint8_t *bdaddr = (uint8_t *)hciemu_get_client_bdaddr(data->hciemu);
+	bt_bdaddr_t remote_addr;
+	bt_status_t status;
+
+	bdaddr2android((const bdaddr_t *)bdaddr, &remote_addr.address);
+
+	if (data->cb_count == 4) {
+		data->cb_count--;
+		status = data->if_bluetooth->create_bond(&remote_addr);
+		check_expected_status(status);
+	}
+}
+
+static void test_bond_create_pin_success(const void *test_data)
+{
+	struct test_data *data = tester_get_data();
+	struct bthost *bthost = hciemu_client_get_host(data->hciemu);
+
+	static uint8_t pair_device_pin[] = { 0x30, 0x30, 0x30, 0x30 };
+	const void *pin = pair_device_pin;
+	uint8_t pin_len = 4;
+
+	init_test_conditions(data);
+
+	mgmt_register(data->mgmt, MGMT_EV_DEVICE_FOUND, data->mgmt_index,
+					bond_device_found_callback, data, NULL);
+
+	bthost_set_pin_code(bthost, pin, pin_len);
+
+	data->if_bluetooth->start_discovery();
+}
+
 /* Test Socket HAL */
 
 static void adapter_socket_state_changed_cb(bt_state_t state)
@@ -3801,6 +3915,11 @@ int main(int argc, char *argv[])
 				setup_enabled_adapter,
 				test_dev_setprop_disctimeout_fail, teardown);
 
+	test_bredrle("Bluetooth Create Bond PIN - Success",
+					&bt_bond_create_pin_success_test,
+					setup_enabled_adapter,
+					test_bond_create_pin_success, teardown);
+
 	test_bredrle("Socket Init", NULL, setup_socket_interface,
 						test_dummy, teardown);
 
-- 
1.8.5.2


^ permalink raw reply related

* [PATCH 01/10] android/tester: Coding style and syntax fix
From: Grzegorz Kolodziejczyk @ 2014-01-23 16:57 UTC (permalink / raw)
  To: linux-bluetooth

Remove white spaces, break lines over 80 characters, redundand braces
for single statement blocks.
---
 android/android-tester.c | 51 ++++++++++++++++++++++++------------------------
 1 file changed, 26 insertions(+), 25 deletions(-)

diff --git a/android/android-tester.c b/android/android-tester.c
index 9a17612..4bd48d6 100644
--- a/android/android-tester.c
+++ b/android/android-tester.c
@@ -690,9 +690,8 @@ static void discovery_state_changed_cb(bt_discovery_state_t state)
 	struct test_data *data = tester_get_data();
 	const struct generic_data *test = data->test_data;
 
-	if (test && test->expected_hal_cb.discovery_state_changed_cb) {
+	if (test && test->expected_hal_cb.discovery_state_changed_cb)
 		test->expected_hal_cb.discovery_state_changed_cb(state);
-	}
 }
 
 static void discovery_device_found_cb(int num_properties,
@@ -837,10 +836,9 @@ static void device_found_cb(int num_properties, bt_property_t *properties)
 	struct test_data *data = tester_get_data();
 	const struct generic_data *test = data->test_data;
 
-	if (data->test_init_done && test->expected_hal_cb.device_found_cb) {
+	if (data->test_init_done && test->expected_hal_cb.device_found_cb)
 		test->expected_hal_cb.device_found_cb(num_properties,
 								properties);
-	}
 }
 
 static void check_count_properties_cb(bt_status_t status, int num_properties,
@@ -852,7 +850,6 @@ static void check_count_properties_cb(bt_status_t status, int num_properties,
 		check_expected_property(properties[i]);
 }
 
-
 static void adapter_properties_cb(bt_status_t status, int num_properties,
 						bt_property_t *properties)
 {
@@ -860,11 +857,9 @@ static void adapter_properties_cb(bt_status_t status, int num_properties,
 	const struct generic_data *test = data->test_data;
 
 	if (data->test_init_done &&
-				test->expected_hal_cb.adapter_properties_cb) {
-		test->expected_hal_cb.adapter_properties_cb(
-							status, num_properties,
-							properties);
-	}
+				test->expected_hal_cb.adapter_properties_cb)
+		test->expected_hal_cb.adapter_properties_cb(status,
+						num_properties, properties);
 }
 
 static void remote_test_device_properties_cb(bt_status_t status,
@@ -908,10 +903,9 @@ static void remote_device_properties_cb(bt_status_t status,
 	const struct generic_data *test = data->test_data;
 
 	if (data->test_init_done &&
-			test->expected_hal_cb.remote_device_properties_cb) {
+			test->expected_hal_cb.remote_device_properties_cb)
 		test->expected_hal_cb.remote_device_properties_cb(status,
 					bd_addr, num_properties, properties);
-	}
 }
 
 static bt_bdaddr_t enable_done_bdaddr_val = { {0x00} };
@@ -1324,7 +1318,8 @@ static struct priority_property setprop_scanmode_none_props[] = {
 	},
 };
 
-static const struct generic_data bluetooth_setprop_scanmode_none_success2_test = {
+static const struct generic_data
+			bluetooth_setprop_scanmode_none_success2_test = {
 	.expected_hal_cb.adapter_properties_cb = check_count_properties_cb,
 	.expected_properties_num = 1,
 	.expected_properties = setprop_scanmode_none_props,
@@ -1951,7 +1946,6 @@ static bt_callbacks_t bt_callbacks = {
 	.le_test_mode_cb = NULL
 };
 
-
 static void setup(struct test_data *data)
 {
 	const hw_module_t *module;
@@ -2093,7 +2087,8 @@ static void test_enable(const void *test_data)
 
 	init_test_conditions(data);
 
-	bdaddr2android((const bdaddr_t *)bdaddr, &enable_done_bdaddr_val.address);
+	bdaddr2android((const bdaddr_t *)bdaddr,
+					&enable_done_bdaddr_val.address);
 
 	adapter_status = data->if_bluetooth->enable();
 	check_expected_status(adapter_status);
@@ -2108,7 +2103,8 @@ static void test_enable_done(const void *test_data)
 
 	init_test_conditions(data);
 
-	bdaddr2android((const bdaddr_t *)bdaddr, &enable_done_bdaddr_val.address);
+	bdaddr2android((const bdaddr_t *)bdaddr,
+					&enable_done_bdaddr_val.address);
 
 	adapter_status = data->if_bluetooth->enable();
 	check_expected_status(adapter_status);
@@ -2170,7 +2166,8 @@ static void test_getprop_bdaddr_success(const void *test_data)
 
 	init_test_conditions(data);
 
-	bdaddr2android((const bdaddr_t *)bdaddr, &test_getprop_bdaddr_val.address);
+	bdaddr2android((const bdaddr_t *)bdaddr,
+					&test_getprop_bdaddr_val.address);
 
 	adapter_status = data->if_bluetooth->get_adapter_property(prop.type);
 	check_expected_status(adapter_status);
@@ -3374,7 +3371,6 @@ static void emu_powered_complete(uint16_t opcode, uint8_t status,
 	bt_status = data->if_hid->connect(&bdaddr);
 	if (bt_status != BT_STATUS_SUCCESS)
 		tester_setup_failed();
-
 }
 
 static void setup_hidhost_connect(const void *test_data)
@@ -3535,15 +3531,20 @@ int main(int argc, char *argv[])
 
 	test_bredrle("Bluetooth Init", NULL, setup_base, test_dummy, teardown);
 
-	test_bredrle("Bluetooth Enable - Success", &bluetooth_enable_success_test,
-					setup_base, test_enable, teardown);
+	test_bredrle("Bluetooth Enable - Success",
+						&bluetooth_enable_success_test,
+						setup_base, test_enable,
+						teardown);
 
 	test_bredrle("Bluetooth Enable - Success 2",
-			&bluetooth_enable_success2_test, setup_enabled_adapter,
-			test_enable_done, teardown);
-
-	test_bredrle("Bluetooth Disable - Success", &bluetooth_disable_success_test,
-			setup_enabled_adapter, test_disable, teardown);
+						&bluetooth_enable_success2_test,
+						setup_enabled_adapter,
+						test_enable_done, teardown);
+
+	test_bredrle("Bluetooth Disable - Success",
+						&bluetooth_disable_success_test,
+						setup_enabled_adapter,
+						test_disable, teardown);
 
 	test_bredrle("Bluetooth Set BDNAME - Success",
 					&bluetooth_setprop_bdname_success_test,
-- 
1.8.5.2


^ permalink raw reply related

* Re: [PATCH] android/a2dp: Free device outside of notify function
From: Luiz Augusto von Dentz @ 2014-01-23 16:43 UTC (permalink / raw)
  To: Andrei Emeltchenko; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <1390490779-28954-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

Hi Andrei,

On Thu, Jan 23, 2014 at 5:26 PM, Andrei Emeltchenko
<Andrei.Emeltchenko.news@gmail.com> wrote:
> From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
>
> device_free() was used inside notify_state() function based on parameter
> which makes it complex to follow. Change logic so that notify_state()
> only notifies and the other code makes device_free().
> ---
>  android/a2dp.c | 10 +++++-----
>  1 file changed, 5 insertions(+), 5 deletions(-)
>
> diff --git a/android/a2dp.c b/android/a2dp.c
> index 572e0d1..d043c04 100644
> --- a/android/a2dp.c
> +++ b/android/a2dp.c
> @@ -189,11 +189,6 @@ static void bt_a2dp_notify_state(struct a2dp_device *dev, uint8_t state)
>
>         ipc_send_notif(HAL_SERVICE_ID_A2DP, HAL_EV_A2DP_CONN_STATE, sizeof(ev),
>                                                                         &ev);
> -
> -       if (state != HAL_A2DP_STATE_DISCONNECTED)
> -               return;
> -
> -       a2dp_device_free(dev);
>  }
>
>  static void bt_audio_notify_state(struct a2dp_setup *setup, uint8_t state)
> @@ -221,6 +216,7 @@ static void disconnect_cb(void *user_data)
>         struct a2dp_device *dev = user_data;
>
>         bt_a2dp_notify_state(dev, HAL_A2DP_STATE_DISCONNECTED);
> +       a2dp_device_free(dev);
>  }
>
>  static int sbc_check_config(void *caps, uint8_t caps_len, void *conf,
> @@ -460,6 +456,7 @@ static gboolean idle_timeout(gpointer user_data)
>
>         error("avdtp_discover: %s", strerror(-err));
>         bt_a2dp_notify_state(dev, HAL_A2DP_STATE_DISCONNECTED);
> +       a2dp_device_free(dev);
>
>         return FALSE;
>  }
> @@ -474,6 +471,7 @@ static void signaling_connect_cb(GIOChannel *chan, GError *err,
>
>         if (err) {
>                 bt_a2dp_notify_state(dev, HAL_A2DP_STATE_DISCONNECTED);
> +               a2dp_device_free(dev);
>                 error("%s", err->message);
>                 return;
>         }
> @@ -519,6 +517,7 @@ static void signaling_connect_cb(GIOChannel *chan, GError *err,
>
>  failed:
>         bt_a2dp_notify_state(dev, HAL_A2DP_STATE_DISCONNECTED);
> +       a2dp_device_free(dev);
>  }
>
>  static void bt_a2dp_connect(const void *buf, uint16_t len)
> @@ -581,6 +580,7 @@ static void bt_a2dp_disconnect(const void *buf, uint16_t len)
>
>         if (dev->io) {
>                 bt_a2dp_notify_state(dev, HAL_A2DP_STATE_DISCONNECTED);
> +               a2dp_device_free(dev);
>                 goto failed;
>         }
>
> --
> 1.8.3.2

It used to be like that and we changed because now you have to call
a2dp_device_free in all places where bt_a2dp_notify_state(dev,
HAL_A2DP_STATE_DISCONNECTED); is called.


-- 
Luiz Augusto von Dentz

^ permalink raw reply

* [PATCH BlueZ 8/8] android/AVRCP: Add initial socket handling
From: Luiz Augusto von Dentz @ 2014-01-23 16:39 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1390495198-28400-1-git-send-email-luiz.dentz@gmail.com>

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

This adds the initial socket listening and handling incoming connections.
---
 android/avrcp.c | 128 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 128 insertions(+)

diff --git a/android/avrcp.c b/android/avrcp.c
index 02dbb68..a230ab8 100644
--- a/android/avrcp.c
+++ b/android/avrcp.c
@@ -28,6 +28,7 @@
 #include <stdbool.h>
 #include <glib.h>
 
+#include "btio/btio.h"
 #include "lib/bluetooth.h"
 #include "lib/sdp.h"
 #include "lib/sdp_lib.h"
@@ -36,6 +37,7 @@
 #include "avrcp.h"
 #include "hal-msg.h"
 #include "ipc.h"
+#include "avctp.h"
 
 #define L2CAP_PSM_AVCTP 0x17
 
@@ -46,6 +48,13 @@
 
 static bdaddr_t adapter_addr;
 static uint32_t record_id = 0;
+static GSList *devices = NULL;
+static GIOChannel *server = NULL;
+
+struct avrcp_device {
+	bdaddr_t	dst;
+	struct avctp	*session;
+};
 
 static const struct ipc_handler cmd_handlers[] = {
 };
@@ -118,14 +127,124 @@ static sdp_record_t *avrcp_record(void)
 	return record;
 }
 
+static void avrcp_device_free(void *data)
+{
+	struct avrcp_device *dev = data;
+
+	if (dev->session)
+		avctp_shutdown(dev->session);
+
+	devices = g_slist_remove(devices, dev);
+	g_free(dev);
+}
+
+static struct avrcp_device *avrcp_device_new(const bdaddr_t *dst)
+{
+	struct avrcp_device *dev;
+
+	dev = g_new0(struct avrcp_device, 1);
+	bacpy(&dev->dst, dst);
+	devices = g_slist_prepend(devices, dev);
+
+	return dev;
+}
+
+static int device_cmp(gconstpointer s, gconstpointer user_data)
+{
+	const struct avrcp_device *dev = s;
+	const bdaddr_t *dst = user_data;
+
+	return bacmp(&dev->dst, dst);
+}
+
+static void disconnect_cb(void *data)
+{
+	struct avrcp_device *dev = data;
+
+	DBG("");
+
+	dev->session = NULL;
+
+	avrcp_device_free(dev);
+}
+
+static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
+{
+	struct avrcp_device *dev;
+	bdaddr_t src, dst;
+	char address[18];
+	uint16_t imtu, omtu;
+	GError *gerr = NULL;
+	GSList *l;
+	int fd;
+
+	if (err) {
+		error("%s", err->message);
+		return;
+	}
+
+	bt_io_get(chan, &gerr,
+			BT_IO_OPT_SOURCE_BDADDR, &src,
+			BT_IO_OPT_DEST_BDADDR, &dst,
+			BT_IO_OPT_IMTU, &imtu,
+			BT_IO_OPT_OMTU, &omtu,
+			BT_IO_OPT_INVALID);
+	if (gerr) {
+		error("%s", gerr->message);
+		g_error_free(gerr);
+		g_io_channel_shutdown(chan, TRUE, NULL);
+		return;
+	}
+
+	ba2str(&dst, address);
+	DBG("Incoming connection from %s", address);
+
+	l = g_slist_find_custom(devices, &dst, device_cmp);
+	if (l) {
+		error("Unexpected connection");
+		return;
+	}
+
+	fd = g_io_channel_unix_get_fd(chan);
+
+	dev = avrcp_device_new(&dst);
+	dev->session = avctp_new(fd, imtu, omtu, 0x0100);
+
+	if (!dev->session) {
+		avrcp_device_free(dev);
+		return;
+	}
+
+	avctp_set_destroy_cb(dev->session, disconnect_cb, dev);
+
+	/* FIXME: get the real name of the device */
+	avctp_init_uinput(dev->session, "bluetooth", address);
+
+	g_io_channel_set_close_on_unref(chan, FALSE);
+
+	DBG("%s connected", address);
+}
+
 bool bt_avrcp_register(const bdaddr_t *addr)
 {
+	GError *err = NULL;
 	sdp_record_t *rec;
 
 	DBG("");
 
 	bacpy(&adapter_addr, addr);
 
+	server = bt_io_listen(connect_cb, NULL, NULL, NULL, &err,
+				BT_IO_OPT_SOURCE_BDADDR, &adapter_addr,
+				BT_IO_OPT_PSM, L2CAP_PSM_AVCTP,
+				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
+				BT_IO_OPT_INVALID);
+	if (!server) {
+		error("Failed to listen on AVDTP channel: %s", err->message);
+		g_error_free(err);
+		return false;
+	}
+
 	rec = avrcp_record();
 	if (!rec) {
 		error("Failed to allocate AVRCP record");
@@ -149,8 +268,17 @@ void bt_avrcp_unregister(void)
 {
 	DBG("");
 
+	g_slist_free_full(devices, avrcp_device_free);
+	devices = NULL;
+
 	ipc_unregister(HAL_SERVICE_ID_AVRCP);
 
 	bt_adapter_remove_record(record_id);
 	record_id = 0;
+
+	if (server) {
+		g_io_channel_shutdown(server, TRUE, NULL);
+		g_io_channel_unref(server);
+		server = NULL;
+	}
 }
-- 
1.8.4.2


^ permalink raw reply related

* [PATCH BlueZ 7/8] android/AVCTP: Add avctp_set_destroy_cb
From: Luiz Augusto von Dentz @ 2014-01-23 16:39 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1390495198-28400-1-git-send-email-luiz.dentz@gmail.com>

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

This adds avctp_set_destroy_cb that can be use to set a callback when
the AVCTP has been disconnected.
---
 android/avctp.c | 13 +++++++++++++
 android/avctp.h |  3 +++
 2 files changed, 16 insertions(+)

diff --git a/android/avctp.c b/android/avctp.c
index a31dcc6..87e26be 100644
--- a/android/avctp.c
+++ b/android/avctp.c
@@ -175,6 +175,9 @@ struct avctp {
 	uint8_t key_quirks[256];
 	struct key_pressed key;
 	uint16_t version;
+
+	avctp_destroy_cb_t destroy;
+	void *data;
 };
 
 struct avctp_passthrough_handler {
@@ -1446,6 +1449,13 @@ int avctp_connect_browsing(struct avctp *session, int fd, size_t imtu,
 	return 0;
 }
 
+void avctp_set_destroy_cb(struct avctp *session, avctp_destroy_cb_t cb,
+							void *user_data)
+{
+	session->destroy = cb;
+	session->data = user_data;
+}
+
 void avctp_shutdown(struct avctp *session)
 {
 	if (!session)
@@ -1457,6 +1467,9 @@ void avctp_shutdown(struct avctp *session)
 	if (session->control)
 		avctp_channel_destroy(session->control);
 
+	if (session->destroy)
+		session->destroy(session->data);
+
 	if (session->key.timer > 0)
 		g_source_remove(session->key.timer);
 
diff --git a/android/avctp.h b/android/avctp.h
index 99aaf95..a22bf13 100644
--- a/android/avctp.h
+++ b/android/avctp.h
@@ -103,6 +103,9 @@ typedef size_t (*avctp_browsing_pdu_cb) (struct avctp *session,
 typedef void (*avctp_destroy_cb_t) (void *user_data);
 
 struct avctp *avctp_new(int fd, size_t imtu, size_t omtu, uint16_t version);
+void avctp_set_destroy_cb(struct avctp *session, avctp_destroy_cb_t cb,
+							void *user_data);
+
 int avctp_init_uinput(struct avctp *session, const char *name,
 							const char *address);
 int avctp_connect_browsing(struct avctp *session, int fd, size_t imtu,
-- 
1.8.4.2


^ permalink raw reply related

* [PATCH BlueZ 6/8] android/AVRCP: Add implementation of SDP record
From: Luiz Augusto von Dentz @ 2014-01-23 16:39 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1390495198-28400-1-git-send-email-luiz.dentz@gmail.com>

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

This adds the following record:

Service Name: AVRCP TG
Service RecHandle: 0x10002
Service Class ID List:
  "AV Remote Target" (0x110c)
Protocol Descriptor List:
  "L2CAP" (0x0100)
    PSM: 23
  "AVCTP" (0x0017)
    uint16: 0x103
Profile Descriptor List:
  "AV Remote" (0x110e)
    Version: 0x0100
---
 android/avrcp.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 97 insertions(+)

diff --git a/android/avrcp.c b/android/avrcp.c
index 707506b..02dbb68 100644
--- a/android/avrcp.c
+++ b/android/avrcp.c
@@ -29,22 +29,116 @@
 #include <glib.h>
 
 #include "lib/bluetooth.h"
+#include "lib/sdp.h"
+#include "lib/sdp_lib.h"
 #include "log.h"
+#include "bluetooth.h"
 #include "avrcp.h"
 #include "hal-msg.h"
 #include "ipc.h"
 
+#define L2CAP_PSM_AVCTP 0x17
+
+#define AVRCP_FEATURE_CATEGORY_1	0x0001
+#define AVRCP_FEATURE_CATEGORY_2	0x0002
+#define AVRCP_FEATURE_CATEGORY_3	0x0004
+#define AVRCP_FEATURE_CATEGORY_4	0x0008
+
 static bdaddr_t adapter_addr;
+static uint32_t record_id = 0;
 
 static const struct ipc_handler cmd_handlers[] = {
 };
 
+static sdp_record_t *avrcp_record(void)
+{
+	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
+	uuid_t root_uuid, l2cap, avctp, avrtg;
+	sdp_profile_desc_t profile[1];
+	sdp_list_t *aproto_control, *proto_control[2];
+	sdp_record_t *record;
+	sdp_data_t *psm, *version, *features;
+	uint16_t lp = L2CAP_PSM_AVCTP;
+	uint16_t avrcp_ver = 0x0100, avctp_ver = 0x0103;
+	uint16_t feat = ( AVRCP_FEATURE_CATEGORY_1 |
+					AVRCP_FEATURE_CATEGORY_2 |
+					AVRCP_FEATURE_CATEGORY_3 |
+					AVRCP_FEATURE_CATEGORY_4);
+
+	record = sdp_record_alloc();
+	if (!record)
+		return NULL;
+
+	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
+	root = sdp_list_append(0, &root_uuid);
+	sdp_set_browse_groups(record, root);
+
+	/* Service Class ID List */
+	sdp_uuid16_create(&avrtg, AV_REMOTE_TARGET_SVCLASS_ID);
+	svclass_id = sdp_list_append(0, &avrtg);
+	sdp_set_service_classes(record, svclass_id);
+
+	/* Protocol Descriptor List */
+	sdp_uuid16_create(&l2cap, L2CAP_UUID);
+	proto_control[0] = sdp_list_append(0, &l2cap);
+	psm = sdp_data_alloc(SDP_UINT16, &lp);
+	proto_control[0] = sdp_list_append(proto_control[0], psm);
+	apseq = sdp_list_append(0, proto_control[0]);
+
+	sdp_uuid16_create(&avctp, AVCTP_UUID);
+	proto_control[1] = sdp_list_append(0, &avctp);
+	version = sdp_data_alloc(SDP_UINT16, &avctp_ver);
+	proto_control[1] = sdp_list_append(proto_control[1], version);
+	apseq = sdp_list_append(apseq, proto_control[1]);
+
+	aproto_control = sdp_list_append(0, apseq);
+	sdp_set_access_protos(record, aproto_control);
+
+	/* Bluetooth Profile Descriptor List */
+	sdp_uuid16_create(&profile[0].uuid, AV_REMOTE_PROFILE_ID);
+	profile[0].version = avrcp_ver;
+	pfseq = sdp_list_append(0, &profile[0]);
+	sdp_set_profile_descs(record, pfseq);
+
+	features = sdp_data_alloc(SDP_UINT16, &feat);
+	sdp_attr_add(record, SDP_ATTR_SUPPORTED_FEATURES, features);
+
+	sdp_set_info_attr(record, "AVRCP TG", 0, 0);
+
+	sdp_data_free(psm);
+	sdp_data_free(version);
+	sdp_list_free(proto_control[0], NULL);
+	sdp_list_free(proto_control[1], NULL);
+	sdp_list_free(apseq, NULL);
+	sdp_list_free(aproto_control, NULL);
+	sdp_list_free(pfseq, NULL);
+	sdp_list_free(root, NULL);
+	sdp_list_free(svclass_id, NULL);
+
+	return record;
+}
+
 bool bt_avrcp_register(const bdaddr_t *addr)
 {
+	sdp_record_t *rec;
+
 	DBG("");
 
 	bacpy(&adapter_addr, addr);
 
+	rec = avrcp_record();
+	if (!rec) {
+		error("Failed to allocate AVRCP record");
+		return false;
+	}
+
+	if (bt_adapter_add_record(rec, 0) < 0) {
+		error("Failed to register AVRCP record");
+		sdp_record_free(rec);
+		return false;
+	}
+	record_id = rec->handle;
+
 	ipc_register(HAL_SERVICE_ID_AVRCP, cmd_handlers,
 						G_N_ELEMENTS(cmd_handlers));
 
@@ -56,4 +150,7 @@ void bt_avrcp_unregister(void)
 	DBG("");
 
 	ipc_unregister(HAL_SERVICE_ID_AVRCP);
+
+	bt_adapter_remove_record(record_id);
+	record_id = 0;
 }
-- 
1.8.4.2


^ permalink raw reply related

* [PATCH BlueZ 5/8] android/haltest: Add init and cleanup calls to rc methods
From: Luiz Augusto von Dentz @ 2014-01-23 16:39 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1390495198-28400-1-git-send-email-luiz.dentz@gmail.com>

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

---
 android/Android.mk                     |  1 +
 android/Makefile.am                    |  1 +
 android/client/haltest.c               |  2 ++
 android/client/if-bt.c                 |  2 +-
 android/client/if-main.h               |  2 ++
 android/client/{if-audio.c => if-rc.c} | 44 +++++++++++++---------------------
 6 files changed, 23 insertions(+), 29 deletions(-)
 copy android/client/{if-audio.c => if-rc.c} (57%)

diff --git a/android/Android.mk b/android/Android.mk
index 1e1b60c..99dda1a 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -130,6 +130,7 @@ LOCAL_SRC_FILES := \
 	bluez/android/client/tabcompletion.c \
 	bluez/android/client/if-audio.c \
 	bluez/android/client/if-av.c \
+	bluez/android/client/if-rc.c \
 	bluez/android/client/if-bt.c \
 	bluez/android/client/if-hf.c \
 	bluez/android/client/if-hh.c \
diff --git a/android/Makefile.am b/android/Makefile.am
index 9e96d55..57e8518 100644
--- a/android/Makefile.am
+++ b/android/Makefile.am
@@ -85,6 +85,7 @@ android_haltest_SOURCES = android/client/haltest.c \
 				android/client/tabcompletion.c \
 				android/client/if-main.h \
 				android/client/if-av.c \
+				android/client/if-rc.c \
 				android/client/if-bt.c \
 				android/client/if-gatt.c \
 				android/client/if-hf.c \
diff --git a/android/client/haltest.c b/android/client/haltest.c
index f4d1ade..114fe31 100644
--- a/android/client/haltest.c
+++ b/android/client/haltest.c
@@ -34,6 +34,7 @@ const struct interface *interfaces[] = {
 	&audio_if,
 	&bluetooth_if,
 	&av_if,
+	&rc_if,
 	&gatt_if,
 	&gatt_client_if,
 	&gatt_server_if,
@@ -382,6 +383,7 @@ static void init(void)
 	static const char * const inames[] = {
 		BT_PROFILE_HANDSFREE_ID,
 		BT_PROFILE_ADVANCED_AUDIO_ID,
+		BT_PROFILE_AV_RC_ID,
 		BT_PROFILE_HEALTH_ID,
 		BT_PROFILE_HIDHOST_ID,
 		BT_PROFILE_PAN_ID,
diff --git a/android/client/if-bt.c b/android/client/if-bt.c
index 6bfb439..8dcffea 100644
--- a/android/client/if-bt.c
+++ b/android/client/if-bt.c
@@ -760,7 +760,7 @@ static void get_profile_interface_p(int argc, const char **argv)
 	else if (strcmp(BT_PROFILE_PAN_ID, id) == 0)
 		pif = (const void **) &if_pan;
 	else if (strcmp(BT_PROFILE_AV_RC_ID, id) == 0)
-		pif = &dummy; /* TODO: change when if_rc is there */
+		pif = (const void **) &if_rc;
 	else if (strcmp(BT_PROFILE_GATT_ID, id) == 0)
 		pif = (const void **) &if_gatt;
 	else
diff --git a/android/client/if-main.h b/android/client/if-main.h
index 2b22fc4..d82358e 100644
--- a/android/client/if-main.h
+++ b/android/client/if-main.h
@@ -48,6 +48,7 @@ extern audio_hw_device_t *if_audio;
 /* Interfaces from hal that can be populated during application lifetime */
 extern const bt_interface_t *if_bluetooth;
 extern const btav_interface_t *if_av;
+extern const btrc_interface_t *if_rc;
 extern const bthf_interface_t *if_hf;
 extern const bthh_interface_t *if_hh;
 extern const btpan_interface_t *if_pan;
@@ -68,6 +69,7 @@ struct interface {
 extern const struct interface audio_if;
 extern const struct interface bluetooth_if;
 extern const struct interface av_if;
+extern const struct interface rc_if;
 extern const struct interface gatt_if;
 extern const struct interface gatt_client_if;
 extern const struct interface gatt_server_if;
diff --git a/android/client/if-audio.c b/android/client/if-rc.c
similarity index 57%
copy from android/client/if-audio.c
copy to android/client/if-rc.c
index 203e088..58fb892 100644
--- a/android/client/if-audio.c
+++ b/android/client/if-rc.c
@@ -18,41 +18,29 @@
 #include "if-main.h"
 #include "../hal-utils.h"
 
-audio_hw_device_t *if_audio = NULL;
+const btrc_interface_t *if_rc = NULL;
 
-static void init_p(int argc, const char **argv)
-{
-	int err;
-	const hw_module_t *module;
-	audio_hw_device_t *device;
+static btrc_callbacks_t rc_cbacks = {
+	.size = sizeof(rc_cbacks),
+};
 
-	err = hw_get_module_by_class(AUDIO_HARDWARE_MODULE_ID,
-					AUDIO_HARDWARE_MODULE_ID_A2DP, &module);
-	if (err) {
-		haltest_error("hw_get_module_by_class returned %d\n", err);
-		return;
-	}
+/* init */
 
-	err = audio_hw_device_open(module, &device);
-	if (err)
-		haltest_error("audio_hw_device_open returned %d\n", err);
+static void init_p(int argc, const char **argv)
+{
+	RETURN_IF_NULL(if_rc);
 
-	if_audio = device;
+	EXEC(if_rc->init, &rc_cbacks);
 }
 
+/* cleanup */
+
 static void cleanup_p(int argc, const char **argv)
 {
-	int err;
-
-	RETURN_IF_NULL(if_audio);
-
-	err = audio_hw_device_close(if_audio);
-	if (err < 0) {
-		haltest_error("audio_hw_device_close returned %d\n", err);
-		return;
-	}
+	RETURN_IF_NULL(if_rc);
 
-	if_audio = NULL;
+	EXECV(if_rc->cleanup);
+	if_rc = NULL;
 }
 
 static struct method methods[] = {
@@ -61,7 +49,7 @@ static struct method methods[] = {
 	END_METHOD
 };
 
-const struct interface audio_if = {
-	.name = "audio",
+const struct interface rc_if = {
+	.name = "rc",
 	.methods = methods
 };
-- 
1.8.4.2


^ permalink raw reply related

* [PATCH BlueZ 4/8]  android: Add initial skeleton for AVRCP in the HAL
From: Luiz Augusto von Dentz @ 2014-01-23 16:39 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1390495198-28400-1-git-send-email-luiz.dentz@gmail.com>

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

---
 android/Android.mk      |  1 +
 android/Makefile.am     |  1 +
 android/hal-avrcp.c     | 87 +++++++++++++++++++++++++++++++++++++++++++++++++
 android/hal-bluetooth.c |  3 ++
 android/hal.h           |  2 ++
 5 files changed, 94 insertions(+)
 create mode 100644 android/hal-avrcp.c

diff --git a/android/Android.mk b/android/Android.mk
index 45ceeb2..1e1b60c 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -96,6 +96,7 @@ LOCAL_SRC_FILES := \
 	bluez/android/hal-hidhost.c \
 	bluez/android/hal-pan.c \
 	bluez/android/hal-a2dp.c \
+	bluez/android/hal-avrcp.c \
 	bluez/android/hal-utils.c \
 
 LOCAL_C_INCLUDES += \
diff --git a/android/Makefile.am b/android/Makefile.am
index 47e7551..9e96d55 100644
--- a/android/Makefile.am
+++ b/android/Makefile.am
@@ -50,6 +50,7 @@ android_bluetooth_default_la_SOURCES = android/hal.h android/hal-bluetooth.c \
 					android/hal-hidhost.c \
 					android/hal-pan.c \
 					android/hal-a2dp.c \
+					android/hal-avrcp.c \
 					android/hardware/bluetooth.h \
 					android/hardware/bt_av.h \
 					android/hardware/bt_gatt.h \
diff --git a/android/hal-avrcp.c b/android/hal-avrcp.c
new file mode 100644
index 0000000..01d233b
--- /dev/null
+++ b/android/hal-avrcp.c
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2014 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <string.h>
+
+#include "hal-log.h"
+#include "hal.h"
+#include "hal-msg.h"
+#include "hal-ipc.h"
+
+static const btrc_callbacks_t *cbs = NULL;
+
+static bool interface_ready(void)
+{
+	return cbs != NULL;
+}
+
+static bt_status_t init(btrc_callbacks_t *callbacks)
+{
+	struct hal_cmd_register_module cmd;
+	int ret;
+
+	DBG("");
+
+	if (interface_ready())
+		return BT_STATUS_DONE;
+
+	cbs = callbacks;
+
+	cmd.service_id = HAL_SERVICE_ID_AVRCP;
+
+	ret = hal_ipc_cmd(HAL_SERVICE_ID_CORE, HAL_OP_REGISTER_MODULE,
+					sizeof(cmd), &cmd, 0, NULL, NULL);
+
+	if (ret != BT_STATUS_SUCCESS) {
+		cbs = NULL;
+		hal_ipc_unregister(HAL_SERVICE_ID_AVRCP);
+	}
+
+	return ret;
+}
+
+static void cleanup()
+{
+	struct hal_cmd_unregister_module cmd;
+
+	DBG("");
+
+	if (!interface_ready())
+		return;
+
+	cbs = NULL;
+
+	cmd.service_id = HAL_SERVICE_ID_AVRCP;
+
+	hal_ipc_cmd(HAL_SERVICE_ID_CORE, HAL_OP_UNREGISTER_MODULE,
+					sizeof(cmd), &cmd, 0, NULL, NULL);
+
+	hal_ipc_unregister(HAL_SERVICE_ID_AVRCP);
+}
+
+static btrc_interface_t iface = {
+	.size = sizeof(iface),
+	.init = init,
+	.cleanup = cleanup
+};
+
+btrc_interface_t *bt_get_avrcp_interface()
+{
+	return &iface;
+}
diff --git a/android/hal-bluetooth.c b/android/hal-bluetooth.c
index 4f0e7b7..0dac158 100644
--- a/android/hal-bluetooth.c
+++ b/android/hal-bluetooth.c
@@ -762,6 +762,9 @@ static const void *get_profile_interface(const char *profile_id)
 	if (!strcmp(profile_id, BT_PROFILE_ADVANCED_AUDIO_ID))
 		return bt_get_a2dp_interface();
 
+	if (!strcmp(profile_id, BT_PROFILE_AV_RC_ID))
+		return bt_get_avrcp_interface();
+
 	return NULL;
 }
 
diff --git a/android/hal.h b/android/hal.h
index b475411..1ff4fbd 100644
--- a/android/hal.h
+++ b/android/hal.h
@@ -20,11 +20,13 @@
 #include <hardware/bt_hh.h>
 #include <hardware/bt_pan.h>
 #include <hardware/bt_av.h>
+#include <hardware/bt_rc.h>
 
 btsock_interface_t *bt_get_sock_interface(void);
 bthh_interface_t *bt_get_hidhost_interface(void);
 btpan_interface_t *bt_get_pan_interface(void);
 btav_interface_t *bt_get_a2dp_interface(void);
+btrc_interface_t *bt_get_avrcp_interface(void);
 
 void bt_thread_associate(void);
 void bt_thread_disassociate(void);
-- 
1.8.4.2


^ permalink raw reply related

* [PATCH BlueZ 3/8] android: Add initial skeleton for AVRCP in the daemon
From: Luiz Augusto von Dentz @ 2014-01-23 16:39 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1390495198-28400-1-git-send-email-luiz.dentz@gmail.com>

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

---
 android/Android.mk                          |  1 +
 android/Makefile.am                         |  1 +
 plugins/external-dummy.c => android/avrcp.c | 32 ++++++++++++++++++++++-------
 android/{hidhost.h => avrcp.h}              |  6 +++---
 android/main.c                              | 11 ++++++++++
 5 files changed, 41 insertions(+), 10 deletions(-)
 copy plugins/external-dummy.c => android/avrcp.c (62%)
 copy android/{hidhost.h => avrcp.h} (84%)

diff --git a/android/Android.mk b/android/Android.mk
index b43119e..45ceeb2 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -29,6 +29,7 @@ LOCAL_SRC_FILES := \
 	bluez/android/avdtp.c \
 	bluez/android/a2dp.c \
 	bluez/android/avctp.c \
+	bluez/android/avrcp.c \
 	bluez/android/pan.c \
 	bluez/src/log.c \
 	bluez/src/shared/mgmt.c \
diff --git a/android/Makefile.am b/android/Makefile.am
index 41694ee..47e7551 100644
--- a/android/Makefile.am
+++ b/android/Makefile.am
@@ -34,6 +34,7 @@ android_bluetoothd_SOURCES = android/main.c \
 				android/avdtp.h android/avdtp.c \
 				android/a2dp.h android/a2dp.c \
 				android/avctp.h android/avctp.c \
+				android/avrcp.h android/avrcp.c \
 				android/socket.h android/socket.c \
 				android/pan.h android/pan.c \
 				btio/btio.h btio/btio.c \
diff --git a/plugins/external-dummy.c b/android/avrcp.c
similarity index 62%
copy from plugins/external-dummy.c
copy to android/avrcp.c
index ff31290..707506b 100644
--- a/plugins/external-dummy.c
+++ b/android/avrcp.c
@@ -2,6 +2,9 @@
  *
  *  BlueZ - Bluetooth protocol stack for Linux
  *
+ *  Copyright (C) 2014  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
@@ -22,20 +25,35 @@
 #include <config.h>
 #endif
 
-#include "plugin.h"
+#include <stdbool.h>
+#include <glib.h>
+
+#include "lib/bluetooth.h"
 #include "log.h"
+#include "avrcp.h"
+#include "hal-msg.h"
+#include "ipc.h"
+
+static bdaddr_t adapter_addr;
+
+static const struct ipc_handler cmd_handlers[] = {
+};
 
-static int dummy_init(void)
+bool bt_avrcp_register(const bdaddr_t *addr)
 {
 	DBG("");
 
-	return 0;
+	bacpy(&adapter_addr, addr);
+
+	ipc_register(HAL_SERVICE_ID_AVRCP, cmd_handlers,
+						G_N_ELEMENTS(cmd_handlers));
+
+	return true;
 }
 
-static void dummy_exit(void)
+void bt_avrcp_unregister(void)
 {
 	DBG("");
-}
 
-BLUETOOTH_PLUGIN_DEFINE(external_dummy, VERSION,
-		BLUETOOTH_PLUGIN_PRIORITY_LOW, dummy_init, dummy_exit)
+	ipc_unregister(HAL_SERVICE_ID_AVRCP);
+}
diff --git a/android/hidhost.h b/android/avrcp.h
similarity index 84%
copy from android/hidhost.h
copy to android/avrcp.h
index ea14446..6fe7fbf 100644
--- a/android/hidhost.h
+++ b/android/avrcp.h
@@ -2,7 +2,7 @@
  *
  *  BlueZ - Bluetooth protocol stack for Linux
  *
- *  Copyright (C) 2013  Intel Corporation. All rights reserved.
+ *  Copyright (C) 2014  Intel Corporation. All rights reserved.
  *
  *
  *  This program is free software; you can redistribute it and/or modify
@@ -21,5 +21,5 @@
  *
  */
 
-bool bt_hid_register(const bdaddr_t *addr);
-void bt_hid_unregister(void);
+bool bt_avrcp_register(const bdaddr_t *addr);
+void bt_avrcp_unregister(void);
diff --git a/android/main.c b/android/main.c
index 8983a84..c353c4a 100644
--- a/android/main.c
+++ b/android/main.c
@@ -55,6 +55,7 @@
 #include "ipc.h"
 #include "a2dp.h"
 #include "pan.h"
+#include "avrcp.h"
 
 #define STARTUP_GRACE_SECONDS 5
 #define SHUTDOWN_GRACE_SECONDS 10
@@ -107,6 +108,13 @@ static void service_register(const void *buf, uint16_t len)
 		}
 
 		break;
+	case HAL_SERVICE_ID_AVRCP:
+		if (!bt_avrcp_register(&adapter_bdaddr)) {
+			status = HAL_STATUS_FAILED;
+			goto failed;
+		}
+
+		break;
 	default:
 		DBG("service %u not supported", m->service_id);
 		status = HAL_STATUS_FAILED;
@@ -149,6 +157,9 @@ static void service_unregister(const void *buf, uint16_t len)
 	case HAL_SERVICE_ID_PAN:
 		bt_pan_unregister();
 		break;
+	case HAL_SERVICE_ID_AVRCP:
+		bt_avrcp_unregister();
+		break;
 	default:
 		/* This would indicate bug in HAL, as unregister should not be
 		 * called in init failed */
-- 
1.8.4.2


^ permalink raw reply related

* [PATCH BlueZ 2/8] android/AVCTP: Strip dependencies
From: Luiz Augusto von Dentz @ 2014-01-23 16:39 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1390495198-28400-1-git-send-email-luiz.dentz@gmail.com>

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

This strips AVCTP code of any dependency of core and btio to make it
transport agnostic.
---
 android/Android.mk  |   1 +
 android/Makefile.am |   1 +
 android/avctp.c     | 793 ++++++++--------------------------------------------
 android/avctp.h     |  40 +--
 4 files changed, 134 insertions(+), 701 deletions(-)

diff --git a/android/Android.mk b/android/Android.mk
index 43e6036..b43119e 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -28,6 +28,7 @@ LOCAL_SRC_FILES := \
 	bluez/android/audio-ipc.c \
 	bluez/android/avdtp.c \
 	bluez/android/a2dp.c \
+	bluez/android/avctp.c \
 	bluez/android/pan.c \
 	bluez/src/log.c \
 	bluez/src/shared/mgmt.c \
diff --git a/android/Makefile.am b/android/Makefile.am
index 910beb5..41694ee 100644
--- a/android/Makefile.am
+++ b/android/Makefile.am
@@ -33,6 +33,7 @@ android_bluetoothd_SOURCES = android/main.c \
 				android/audio-ipc.h android/audio-ipc.c \
 				android/avdtp.h android/avdtp.c \
 				android/a2dp.h android/a2dp.c \
+				android/avctp.h android/avctp.c \
 				android/socket.h android/socket.c \
 				android/pan.h android/pan.c \
 				btio/btio.h btio/btio.c \
diff --git a/android/avctp.c b/android/avctp.c
index 6669ddc..a31dcc6 100644
--- a/android/avctp.c
+++ b/android/avctp.c
@@ -34,27 +34,20 @@
 #include <unistd.h>
 #include <assert.h>
 #include <signal.h>
+#include <string.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <netinet/in.h>
 
-#include <bluetooth/bluetooth.h>
 #include <bluetooth/sdp.h>
-#include <bluetooth/l2cap.h>
 
 #include <glib.h>
-#include <btio/btio.h>
-
-#include "lib/uuid.h"
-#include "src/adapter.h"
-#include "src/device.h"
 
 #include "log.h"
 #include "error.h"
 #include "uinput.h"
 #include "avctp.h"
-#include "avrcp.h"
 
 /* AV/C Panel 1.23, page 76:
  * command with the pressed value is valid for two seconds
@@ -115,20 +108,6 @@ struct avc_header {
 #error "Unknown byte order"
 #endif
 
-struct avctp_state_callback {
-	avctp_state_cb cb;
-	struct btd_device *dev;
-	unsigned int id;
-	void *user_data;
-};
-
-struct avctp_server {
-	struct btd_adapter *adapter;
-	GIOChannel *control_io;
-	GIOChannel *browsing_io;
-	GSList *sessions;
-};
-
 struct avctp_control_req {
 	struct avctp_pending_req *p;
 	uint8_t code;
@@ -157,7 +136,7 @@ struct avctp_pending_req {
 	int err;
 	avctp_process_cb process;
 	void *data;
-	GDestroyNotify destroy;
+	avctp_destroy_cb_t destroy;
 };
 
 struct avctp_channel {
@@ -173,7 +152,7 @@ struct avctp_channel {
 	GQueue *queue;
 	GSList *processed;
 	guint process_id;
-	GDestroyNotify destroy;
+	avctp_destroy_cb_t destroy;
 };
 
 struct key_pressed {
@@ -182,14 +161,8 @@ struct key_pressed {
 };
 
 struct avctp {
-	struct avctp_server *server;
-	struct btd_device *device;
-
-	avctp_state_t state;
-
 	int uinput;
 
-	guint auth_id;
 	unsigned int passthrough_id;
 	unsigned int unit_id;
 	unsigned int subunit_id;
@@ -201,7 +174,7 @@ struct avctp {
 
 	uint8_t key_quirks[256];
 	struct key_pressed key;
-	bool initiator;
+	uint16_t version;
 };
 
 struct avctp_passthrough_handler {
@@ -221,7 +194,7 @@ struct avctp_browsing_pdu_handler {
 	avctp_browsing_pdu_cb cb;
 	void *user_data;
 	unsigned int id;
-	GDestroyNotify destroy;
+	avctp_destroy_cb_t destroy;
 };
 
 static struct {
@@ -259,10 +232,6 @@ static struct {
 	{ NULL }
 };
 
-static GSList *callbacks = NULL;
-static GSList *servers = NULL;
-
-static void auth_cb(DBusError *derr, void *user_data);
 static gboolean process_queue(gpointer user_data);
 static gboolean avctp_passthrough_rsp(struct avctp *session, uint8_t code,
 					uint8_t subunit, uint8_t *operands,
@@ -488,83 +457,6 @@ static void avctp_channel_destroy(struct avctp_channel *chan)
 	g_free(chan);
 }
 
-static void avctp_disconnected(struct avctp *session)
-{
-	struct avctp_server *server;
-
-	if (!session)
-		return;
-
-	if (session->browsing)
-		avctp_channel_destroy(session->browsing);
-
-	if (session->control)
-		avctp_channel_destroy(session->control);
-
-	if (session->auth_id != 0) {
-		btd_cancel_authorization(session->auth_id);
-		session->auth_id = 0;
-	}
-
-	if (session->key.timer > 0)
-		g_source_remove(session->key.timer);
-
-	if (session->uinput >= 0) {
-		char address[18];
-
-		ba2str(device_get_address(session->device), address);
-		DBG("AVCTP: closing uinput for %s", address);
-
-		ioctl(session->uinput, UI_DEV_DESTROY);
-		close(session->uinput);
-		session->uinput = -1;
-	}
-
-	server = session->server;
-	server->sessions = g_slist_remove(server->sessions, session);
-	btd_device_unref(session->device);
-	g_free(session);
-}
-
-static void avctp_set_state(struct avctp *session, avctp_state_t new_state)
-{
-	GSList *l;
-	avctp_state_t old_state = session->state;
-
-	session->state = new_state;
-
-	for (l = callbacks; l != NULL; l = l->next) {
-		struct avctp_state_callback *cb = l->data;
-
-		if (cb->dev && cb->dev != session->device)
-			continue;
-
-		cb->cb(session->device, old_state, new_state, cb->user_data);
-	}
-
-	switch (new_state) {
-	case AVCTP_STATE_DISCONNECTED:
-		DBG("AVCTP Disconnected");
-		avctp_disconnected(session);
-		break;
-	case AVCTP_STATE_CONNECTING:
-		DBG("AVCTP Connecting");
-		break;
-	case AVCTP_STATE_CONNECTED:
-		DBG("AVCTP Connected");
-		break;
-	case AVCTP_STATE_BROWSING_CONNECTING:
-		DBG("AVCTP Browsing Connecting");
-		break;
-	case AVCTP_STATE_BROWSING_CONNECTED:
-		DBG("AVCTP Browsing Connected");
-		break;
-	default:
-		error("Invalid AVCTP state %d", new_state);
-		return;
-	}
-}
-
 static int avctp_send(struct avctp_channel *control, uint8_t transaction,
 				uint8_t cr, uint8_t code,
 				uint8_t subunit, uint8_t opcode,
@@ -874,7 +766,8 @@ static gboolean session_browsing_cb(GIOChannel *chan, GIOCondition cond,
 	handler = g_slist_nth_data(browsing->handlers, 0);
 	if (handler == NULL) {
 		DBG("handler not found");
-		packet_size += avrcp_browsing_general_reject(operands);
+		/* FIXME: Add general reject */
+		/* packet_size += avrcp_browsing_general_reject(operands); */
 		goto send;
 	}
 
@@ -893,7 +786,6 @@ send:
 
 failed:
 	DBG("AVCTP Browsing: disconnected");
-	avctp_set_state(session, AVCTP_STATE_CONNECTED);
 
 	if (session->browsing) {
 		avctp_channel_destroy(session->browsing);
@@ -966,7 +858,9 @@ static gboolean session_cb(GIOChannel *chan, GIOCondition cond,
 	handler = find_handler(control->handlers, avc->opcode);
 	if (!handler) {
 		DBG("handler not found for 0x%02x", avc->opcode);
-		packet_size += avrcp_handle_vendor_reject(&code, operands);
+		/* FIXME:
+		 * packet_size += avrcp_handle_vendor_reject(&code, operands);
+		 */
 		avc->code = code;
 		goto done;
 	}
@@ -990,11 +884,11 @@ done:
 
 failed:
 	DBG("AVCTP session %p got disconnected", session);
-	avctp_set_state(session, AVCTP_STATE_DISCONNECTED);
+	avctp_shutdown(session);
 	return FALSE;
 }
 
-static int uinput_create(char *name)
+static int uinput_create(const char *name)
 {
 	struct uinput_dev dev;
 	int fd, err, i;
@@ -1049,11 +943,9 @@ static int uinput_create(char *name)
 	return fd;
 }
 
-static void init_uinput(struct avctp *session)
+int avctp_init_uinput(struct avctp *session, const char *name,
+							const char *address)
 {
-	char address[18], name[248 + 1];
-
-	device_get_name(session->device, name, sizeof(name));
 	if (g_str_equal(name, "Nokia CK-20W")) {
 		session->key_quirks[AVC_FORWARD] |= QUIRK_NO_RELEASE;
 		session->key_quirks[AVC_BACKWARD] |= QUIRK_NO_RELEASE;
@@ -1061,24 +953,28 @@ static void init_uinput(struct avctp *session)
 		session->key_quirks[AVC_PAUSE] |= QUIRK_NO_RELEASE;
 	}
 
-	ba2str(device_get_address(session->device), address);
 	session->uinput = uinput_create(address);
-	if (session->uinput < 0)
-		error("AVRCP: failed to init uinput for %s", address);
-	else
-		DBG("AVRCP: uinput initialized for %s", address);
+	if (session->uinput < 0) {
+		error("AVCTP: failed to init uinput for %s", address);
+		return session->uinput;
+	}
+
+	return 0;
 }
 
-static struct avctp_channel *avctp_channel_create(struct avctp *session,
-							GIOChannel *io,
-							GDestroyNotify destroy)
+static struct avctp_channel *avctp_channel_create(struct avctp *session, int fd,
+						size_t imtu, size_t omtu,
+						avctp_destroy_cb_t destroy)
 {
 	struct avctp_channel *chan;
 
 	chan = g_new0(struct avctp_channel, 1);
 	chan->session = session;
-	chan->io = g_io_channel_ref(io);
+	chan->io = g_io_channel_unix_new(fd);
 	chan->queue = g_queue_new();
+	chan->imtu = imtu;
+	chan->omtu = omtu;
+	chan->buffer = g_malloc0(MAX(imtu, omtu));
 	chan->destroy = destroy;
 
 	return chan;
@@ -1103,381 +999,10 @@ static void avctp_destroy_browsing(void *data)
 	chan->handlers = NULL;
 }
 
-static void avctp_connect_browsing_cb(GIOChannel *chan, GError *err,
-							gpointer data)
-{
-	struct avctp *session = data;
-	struct avctp_channel *browsing = session->browsing;
-	char address[18];
-	uint16_t imtu, omtu;
-	GError *gerr = NULL;
-
-	if (err) {
-		error("Browsing: %s", err->message);
-		goto fail;
-	}
-
-	bt_io_get(chan, &gerr,
-			BT_IO_OPT_DEST, &address,
-			BT_IO_OPT_IMTU, &imtu,
-			BT_IO_OPT_OMTU, &omtu,
-			BT_IO_OPT_INVALID);
-	if (gerr) {
-		error("%s", gerr->message);
-		g_io_channel_shutdown(chan, TRUE, NULL);
-		g_io_channel_unref(chan);
-		g_error_free(gerr);
-		goto fail;
-	}
-
-	DBG("AVCTP Browsing: connected to %s", address);
-
-	if (browsing == NULL) {
-		browsing = avctp_channel_create(session, chan,
-						avctp_destroy_browsing);
-		session->browsing = browsing;
-	}
-
-	browsing->imtu = imtu;
-	browsing->omtu = omtu;
-	browsing->buffer = g_malloc0(MAX(imtu, omtu));
-	browsing->watch = g_io_add_watch(session->browsing->io,
-				G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
-				(GIOFunc) session_browsing_cb, session);
-
-	avctp_set_state(session, AVCTP_STATE_BROWSING_CONNECTED);
-
-	/* Process any request that was pending the connection to complete */
-	if (browsing->process_id == 0 && !g_queue_is_empty(browsing->queue))
-		browsing->process_id = g_idle_add(process_queue, browsing);
-
-	return;
-
-fail:
-	avctp_set_state(session, AVCTP_STATE_CONNECTED);
-
-	if (session->browsing) {
-		avctp_channel_destroy(session->browsing);
-		session->browsing = NULL;
-	}
-}
-
-static void avctp_connect_cb(GIOChannel *chan, GError *err, gpointer data)
-{
-	struct avctp *session = data;
-	char address[18];
-	uint16_t imtu, omtu;
-	GError *gerr = NULL;
-
-	if (err) {
-		avctp_set_state(session, AVCTP_STATE_DISCONNECTED);
-		error("%s", err->message);
-		return;
-	}
-
-	bt_io_get(chan, &gerr,
-			BT_IO_OPT_DEST, &address,
-			BT_IO_OPT_IMTU, &imtu,
-			BT_IO_OPT_IMTU, &omtu,
-			BT_IO_OPT_INVALID);
-	if (gerr) {
-		avctp_set_state(session, AVCTP_STATE_DISCONNECTED);
-		error("%s", gerr->message);
-		g_error_free(gerr);
-		return;
-	}
-
-	DBG("AVCTP: connected to %s", address);
-
-	if (session->control == NULL)
-		session->control = avctp_channel_create(session, chan, NULL);
-
-	session->control->imtu = imtu;
-	session->control->omtu = omtu;
-	session->control->buffer = g_malloc0(MAX(imtu, omtu));
-	session->control->watch = g_io_add_watch(session->control->io,
-				G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
-				(GIOFunc) session_cb, session);
-
-	session->passthrough_id = avctp_register_pdu_handler(session,
-						AVC_OP_PASSTHROUGH,
-						handle_panel_passthrough,
-						NULL);
-	session->unit_id = avctp_register_pdu_handler(session,
-						AVC_OP_UNITINFO,
-						handle_unit_info,
-						NULL);
-	session->subunit_id = avctp_register_pdu_handler(session,
-						AVC_OP_SUBUNITINFO,
-						handle_subunit_info,
-						NULL);
-
-	init_uinput(session);
-
-	avctp_set_state(session, AVCTP_STATE_CONNECTED);
-}
-
-static void auth_cb(DBusError *derr, void *user_data)
-{
-	struct avctp *session = user_data;
-	GError *err = NULL;
-
-	session->auth_id = 0;
-
-	if (session->control->watch > 0) {
-		g_source_remove(session->control->watch);
-		session->control->watch = 0;
-	}
-
-	if (derr && dbus_error_is_set(derr)) {
-		error("Access denied: %s", derr->message);
-		avctp_set_state(session, AVCTP_STATE_DISCONNECTED);
-		return;
-	}
-
-	if (!bt_io_accept(session->control->io, avctp_connect_cb, session,
-								NULL, &err)) {
-		error("bt_io_accept: %s", err->message);
-		g_error_free(err);
-		avctp_set_state(session, AVCTP_STATE_DISCONNECTED);
-	}
-}
-
-static struct avctp_server *find_server(GSList *list, struct btd_adapter *a)
-{
-	for (; list; list = list->next) {
-		struct avctp_server *server = list->data;
-
-		if (server->adapter == a)
-			return server;
-	}
-
-	return NULL;
-}
-
-static struct avctp *find_session(GSList *list, struct btd_device *device)
-{
-	for (; list != NULL; list = g_slist_next(list)) {
-		struct avctp *s = list->data;
-
-		if (s->device == device)
-			return s;
-	}
-
-	return NULL;
-}
-
-static struct avctp *avctp_get_internal(struct btd_device *device)
-{
-	struct avctp_server *server;
-	struct avctp *session;
-
-	server = find_server(servers, device_get_adapter(device));
-	if (server == NULL)
-		return NULL;
-
-	session = find_session(server->sessions, device);
-	if (session)
-		return session;
-
-	session = g_new0(struct avctp, 1);
-
-	session->server = server;
-	session->device = btd_device_ref(device);
-	session->state = AVCTP_STATE_DISCONNECTED;
-	session->uinput = -1;
-
-	server->sessions = g_slist_append(server->sessions, session);
-
-	return session;
-}
-
-static void avctp_control_confirm(struct avctp *session, GIOChannel *chan,
-						struct btd_device *dev)
-{
-	const bdaddr_t *src;
-	const bdaddr_t *dst;
-
-	if (session->control != NULL) {
-		error("Control: Refusing unexpected connect");
-		g_io_channel_shutdown(chan, TRUE, NULL);
-		return;
-	}
-
-	avctp_set_state(session, AVCTP_STATE_CONNECTING);
-	session->control = avctp_channel_create(session, chan, NULL);
-
-	src = btd_adapter_get_address(device_get_adapter(dev));
-	dst = device_get_address(dev);
-
-	session->auth_id = btd_request_authorization(src, dst,
-							AVRCP_REMOTE_UUID,
-							auth_cb, session);
-	if (session->auth_id == 0)
-		goto drop;
-
-	session->control->watch = g_io_add_watch(chan, G_IO_ERR | G_IO_HUP |
-						G_IO_NVAL, session_cb, session);
-	return;
-
-drop:
-	avctp_set_state(session, AVCTP_STATE_DISCONNECTED);
-}
-
-static void avctp_browsing_confirm(struct avctp *session, GIOChannel *chan,
-						struct btd_device *dev)
-{
-	GError *err = NULL;
-
-	if (session->control == NULL || session->browsing != NULL) {
-		error("Browsing: Refusing unexpected connect");
-		g_io_channel_shutdown(chan, TRUE, NULL);
-		return;
-	}
-
-	if (bt_io_accept(chan, avctp_connect_browsing_cb, session, NULL,
-								&err)) {
-		avctp_set_state(session, AVCTP_STATE_BROWSING_CONNECTING);
-		return;
-	}
-
-	error("Browsing: %s", err->message);
-	g_error_free(err);
-
-	return;
-}
-
-static void avctp_confirm_cb(GIOChannel *chan, gpointer data)
-{
-	struct avctp *session;
-	char address[18];
-	bdaddr_t src, dst;
-	GError *err = NULL;
-	uint16_t psm;
-	struct btd_device *device;
-
-	bt_io_get(chan, &err,
-			BT_IO_OPT_SOURCE_BDADDR, &src,
-			BT_IO_OPT_DEST_BDADDR, &dst,
-			BT_IO_OPT_DEST, address,
-			BT_IO_OPT_PSM, &psm,
-			BT_IO_OPT_INVALID);
-	if (err) {
-		error("%s", err->message);
-		g_error_free(err);
-		g_io_channel_shutdown(chan, TRUE, NULL);
-		return;
-	}
-
-	DBG("AVCTP: incoming connect from %s", address);
-
-	device = btd_adapter_find_device(adapter_find(&src), &dst);
-	if (!device)
-		return;
-
-	session = avctp_get_internal(device);
-	if (session == NULL)
-		return;
-
-	if (btd_device_get_service(device, AVRCP_REMOTE_UUID) == NULL)
-		btd_device_add_uuid(device, AVRCP_REMOTE_UUID);
-
-	if (btd_device_get_service(device, AVRCP_TARGET_UUID) == NULL)
-		btd_device_add_uuid(device, AVRCP_TARGET_UUID);
-
-	switch (psm) {
-	case AVCTP_CONTROL_PSM:
-		avctp_control_confirm(session, chan, device);
-		break;
-	case AVCTP_BROWSING_PSM:
-		avctp_browsing_confirm(session, chan, device);
-		break;
-	}
-
-	return;
-}
-
-static GIOChannel *avctp_server_socket(const bdaddr_t *src, gboolean master,
-						uint8_t mode, uint16_t psm)
-{
-	GError *err = NULL;
-	GIOChannel *io;
-
-	io = bt_io_listen(NULL, avctp_confirm_cb, NULL,
-				NULL, &err,
-				BT_IO_OPT_SOURCE_BDADDR, src,
-				BT_IO_OPT_PSM, psm,
-				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
-				BT_IO_OPT_MASTER, master,
-				BT_IO_OPT_MODE, mode,
-				BT_IO_OPT_INVALID);
-	if (!io) {
-		error("%s", err->message);
-		g_error_free(err);
-	}
-
-	return io;
-}
-
-int avctp_register(struct btd_adapter *adapter, gboolean master)
-{
-	struct avctp_server *server;
-	const bdaddr_t *src = btd_adapter_get_address(adapter);
-
-	server = g_new0(struct avctp_server, 1);
-
-	server->control_io = avctp_server_socket(src, master, L2CAP_MODE_BASIC,
-							AVCTP_CONTROL_PSM);
-	if (!server->control_io) {
-		g_free(server);
-		return -1;
-	}
-	server->browsing_io = avctp_server_socket(src, master, L2CAP_MODE_ERTM,
-							AVCTP_BROWSING_PSM);
-	if (!server->browsing_io) {
-		if (server->control_io) {
-			g_io_channel_shutdown(server->control_io, TRUE, NULL);
-			g_io_channel_unref(server->control_io);
-			server->control_io = NULL;
-		}
-		g_free(server);
-		return -1;
-	}
-
-	server->adapter = btd_adapter_ref(adapter);
-
-	servers = g_slist_append(servers, server);
-
-	return 0;
-}
-
-void avctp_unregister(struct btd_adapter *adapter)
-{
-	struct avctp_server *server;
-
-	server = find_server(servers, adapter);
-	if (!server)
-		return;
-
-	while (server->sessions)
-		avctp_disconnected(server->sessions->data);
-
-	servers = g_slist_remove(servers, server);
-
-	g_io_channel_shutdown(server->browsing_io, TRUE, NULL);
-	g_io_channel_unref(server->browsing_io);
-	server->browsing_io = NULL;
-
-	g_io_channel_shutdown(server->control_io, TRUE, NULL);
-	g_io_channel_unref(server->control_io);
-	btd_adapter_unref(server->adapter);
-	g_free(server);
-}
-
 static struct avctp_pending_req *pending_create(struct avctp_channel *chan,
 						avctp_process_cb process,
 						void *data,
-						GDestroyNotify destroy)
+						avctp_destroy_cb_t destroy)
 {
 	struct avctp_pending_req *p;
 	GSList *l, *tmp;
@@ -1732,39 +1257,6 @@ int avctp_send_vendordep_req(struct avctp *session, uint8_t code,
 						func, user_data);
 }
 
-unsigned int avctp_add_state_cb(struct btd_device *dev, avctp_state_cb cb,
-							void *user_data)
-{
-	struct avctp_state_callback *state_cb;
-	static unsigned int id = 0;
-
-	state_cb = g_new(struct avctp_state_callback, 1);
-	state_cb->cb = cb;
-	state_cb->dev = dev;
-	state_cb->id = ++id;
-	state_cb->user_data = user_data;
-
-	callbacks = g_slist_append(callbacks, state_cb);
-
-	return state_cb->id;
-}
-
-gboolean avctp_remove_state_cb(unsigned int id)
-{
-	GSList *l;
-
-	for (l = callbacks; l != NULL; l = l->next) {
-		struct avctp_state_callback *cb = l->data;
-		if (cb && cb->id == id) {
-			callbacks = g_slist_remove(callbacks, cb);
-			g_free(cb);
-			return TRUE;
-		}
-	}
-
-	return FALSE;
-}
-
 unsigned int avctp_register_passthrough_handler(struct avctp *session,
 						avctp_passthrough_cb cb,
 						void *user_data)
@@ -1786,29 +1278,18 @@ unsigned int avctp_register_passthrough_handler(struct avctp *session,
 	return handler->id;
 }
 
-bool avctp_unregister_passthrough_handler(unsigned int id)
+bool avctp_unregister_passthrough_handler(struct avctp *session,
+							unsigned int id)
 {
-	GSList *l;
-
-	for (l = servers; l; l = l->next) {
-		struct avctp_server *server = l->data;
-		GSList *s;
+	if (session->handler == NULL)
+		return false;
 
-		for (s = server->sessions; s; s = s->next) {
-			struct avctp *session = s->data;
-
-			if (session->handler == NULL)
-				continue;
-
-			if (session->handler->id == id) {
-				g_free(session->handler);
-				session->handler = NULL;
-				return true;
-			}
-		}
-	}
+	if (session->handler->id != id)
+		return false;
 
-	return false;
+	g_free(session->handler);
+	session->handler = NULL;
+	return true;
 }
 
 unsigned int avctp_register_pdu_handler(struct avctp *session, uint8_t opcode,
@@ -1840,7 +1321,7 @@ unsigned int avctp_register_pdu_handler(struct avctp *session, uint8_t opcode,
 unsigned int avctp_register_browsing_pdu_handler(struct avctp *session,
 						avctp_browsing_pdu_cb cb,
 						void *user_data,
-						GDestroyNotify destroy)
+						avctp_destroy_cb_t destroy)
 {
 	struct avctp_channel *browsing = session->browsing;
 	struct avctp_browsing_pdu_handler *handler;
@@ -1863,165 +1344,129 @@ unsigned int avctp_register_browsing_pdu_handler(struct avctp *session,
 	return handler->id;
 }
 
-gboolean avctp_unregister_pdu_handler(unsigned int id)
+bool avctp_unregister_pdu_handler(struct avctp *session, unsigned int id)
 {
+	struct avctp_channel *control = session->control;
 	GSList *l;
 
-	for (l = servers; l; l = l->next) {
-		struct avctp_server *server = l->data;
-		GSList *s;
-
-		for (s = server->sessions; s; s = s->next) {
-			struct avctp *session = s->data;
-			struct avctp_channel *control = session->control;
-			GSList *h;
+	if (!control)
+		return false;
 
-			if (control == NULL)
-				continue;
+	for (l = control->handlers; l; l = g_slist_next(l)) {
+		struct avctp_pdu_handler *handler = l->data;
 
-			for (h = control->handlers; h; h = h->next) {
-				struct avctp_pdu_handler *handler = h->data;
-
-				if (handler->id != id)
-					continue;
+		if (handler->id != id)
+			continue;
 
-				control->handlers = g_slist_remove(
-							control->handlers,
-							handler);
-				g_free(handler);
-				return TRUE;
-			}
-		}
+		control->handlers = g_slist_remove(control->handlers, handler);
+		g_free(handler);
+		return true;
 	}
 
-	return FALSE;
+	return false;
 }
 
-gboolean avctp_unregister_browsing_pdu_handler(unsigned int id)
+bool avctp_unregister_browsing_pdu_handler(struct avctp *session,
+							unsigned int id)
 {
+	struct avctp_channel *browsing = session->browsing;
 	GSList *l;
 
-	for (l = servers; l; l = l->next) {
-		struct avctp_server *server = l->data;
-		GSList *s;
-
-		for (s = server->sessions; s; s = s->next) {
-			struct avctp *session = s->data;
-			struct avctp_channel *browsing = session->browsing;
-			GSList *h;
-
-			if (browsing == NULL)
-				continue;
+	if (browsing == NULL)
+		return false;
 
-			for (h = browsing->handlers; h; h = h->next) {
-				struct avctp_browsing_pdu_handler *handler =
-								h->data;
+	for (l = browsing->handlers; l; l = g_slist_next(l)) {
+		struct avctp_browsing_pdu_handler *handler = l->data;
 
-				if (handler->id != id)
-					continue;
+		if (handler->id != id)
+			continue;
 
-				browsing->handlers = g_slist_remove(
-							browsing->handlers,
-							handler);
-				g_free(handler);
-				return TRUE;
-			}
-		}
+		browsing->handlers = g_slist_remove(browsing->handlers,
+								handler);
+		g_free(handler);
+		return true;
 	}
 
-	return FALSE;
+	return false;
 }
 
-struct avctp *avctp_connect(struct btd_device *device)
+struct avctp *avctp_new(int fd, size_t imtu, size_t omtu, uint16_t version)
 {
 	struct avctp *session;
-	GError *err = NULL;
-	GIOChannel *io;
-	const bdaddr_t *src;
-
-	session = avctp_get_internal(device);
-	if (!session)
-		return NULL;
-
-	if (session->state > AVCTP_STATE_DISCONNECTED)
-		return session;
-
-	avctp_set_state(session, AVCTP_STATE_CONNECTING);
+	struct avctp_channel *control;
+	GIOCondition cond = G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL;
 
-	src = btd_adapter_get_address(session->server->adapter);
+	session = g_new0(struct avctp, 1);
+	session->version = version;
 
-	io = bt_io_connect(avctp_connect_cb, session, NULL, &err,
-				BT_IO_OPT_SOURCE_BDADDR, src,
-				BT_IO_OPT_DEST_BDADDR,
-				device_get_address(session->device),
-				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
-				BT_IO_OPT_PSM, AVCTP_CONTROL_PSM,
-				BT_IO_OPT_INVALID);
-	if (err) {
-		avctp_set_state(session, AVCTP_STATE_DISCONNECTED);
-		error("%s", err->message);
-		g_error_free(err);
+	control = avctp_channel_create(session, fd, imtu, omtu, NULL);
+	if (!control) {
+		g_free(session);
 		return NULL;
 	}
 
-	session->control = avctp_channel_create(session, io, NULL);
-	session->initiator = true;
-	g_io_channel_unref(io);
+	session->passthrough_id = avctp_register_pdu_handler(session,
+						AVC_OP_PASSTHROUGH,
+						handle_panel_passthrough,
+						NULL);
+	session->unit_id = avctp_register_pdu_handler(session,
+						AVC_OP_UNITINFO,
+						handle_unit_info,
+						NULL);
+	session->subunit_id = avctp_register_pdu_handler(session,
+						AVC_OP_SUBUNITINFO,
+						handle_subunit_info,
+						NULL);
+
+	session->control = control;
+	control->watch = g_io_add_watch(session->control->io, cond,
+						(GIOFunc) session_cb, session);
 
 	return session;
 }
 
-int avctp_connect_browsing(struct avctp *session)
+int avctp_connect_browsing(struct avctp *session, int fd, size_t imtu,
+								size_t omtu)
 {
-	const bdaddr_t *src;
-	GError *err = NULL;
-	GIOChannel *io;
-
-	if (session->state != AVCTP_STATE_CONNECTED)
-		return -ENOTCONN;
-
-	if (session->browsing != NULL)
-		return 0;
+	struct avctp_channel *browsing;
+	GIOCondition cond = G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL;
 
-	avctp_set_state(session, AVCTP_STATE_BROWSING_CONNECTING);
-
-	src = btd_adapter_get_address(session->server->adapter);
-
-	io = bt_io_connect(avctp_connect_browsing_cb, session, NULL, &err,
-				BT_IO_OPT_SOURCE_BDADDR, src,
-				BT_IO_OPT_DEST_BDADDR,
-				device_get_address(session->device),
-				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
-				BT_IO_OPT_PSM, AVCTP_BROWSING_PSM,
-				BT_IO_OPT_MODE, L2CAP_MODE_ERTM,
-				BT_IO_OPT_INVALID);
-	if (err) {
-		error("%s", err->message);
-		g_error_free(err);
-		return -EIO;
-	}
+	if (session->browsing)
+		return -EISCONN;
 
-	session->browsing = avctp_channel_create(session, io,
+	browsing = avctp_channel_create(session, fd, imtu, omtu,
 						avctp_destroy_browsing);
-	g_io_channel_unref(io);
+	if (!browsing)
+		return -EINVAL;
+
+	session->browsing = browsing;
+	browsing->watch = g_io_add_watch(session->browsing->io, cond,
+					(GIOFunc) session_browsing_cb, session);
 
 	return 0;
 }
 
-void avctp_disconnect(struct avctp *session)
+void avctp_shutdown(struct avctp *session)
 {
-	if (session->state == AVCTP_STATE_DISCONNECTED)
+	if (!session)
 		return;
 
-	avctp_set_state(session, AVCTP_STATE_DISCONNECTED);
-}
+	if (session->browsing)
+		avctp_channel_destroy(session->browsing);
 
-struct avctp *avctp_get(struct btd_device *device)
-{
-	return avctp_get_internal(device);
-}
+	if (session->control)
+		avctp_channel_destroy(session->control);
 
-bool avctp_is_initiator(struct avctp *session)
-{
-	return session->initiator;
+	if (session->key.timer > 0)
+		g_source_remove(session->key.timer);
+
+	if (session->uinput >= 0) {
+		DBG("AVCTP: closing uinput");
+
+		ioctl(session->uinput, UI_DEV_DESTROY);
+		close(session->uinput);
+		session->uinput = -1;
+	}
+
+	g_free(session);
 }
diff --git a/android/avctp.h b/android/avctp.h
index f9c665e..99aaf95 100644
--- a/android/avctp.h
+++ b/android/avctp.h
@@ -82,19 +82,6 @@
 
 struct avctp;
 
-typedef enum {
-	AVCTP_STATE_DISCONNECTED = 0,
-	AVCTP_STATE_CONNECTING,
-	AVCTP_STATE_CONNECTED,
-	AVCTP_STATE_BROWSING_CONNECTING,
-	AVCTP_STATE_BROWSING_CONNECTED
-} avctp_state_t;
-
-typedef void (*avctp_state_cb) (struct btd_device *dev,
-				avctp_state_t old_state,
-				avctp_state_t new_state,
-				void *user_data);
-
 typedef bool (*avctp_passthrough_cb) (struct avctp *session,
 					uint8_t op, bool pressed,
 					void *user_data);
@@ -113,34 +100,33 @@ typedef size_t (*avctp_browsing_pdu_cb) (struct avctp *session,
 					uint8_t *operands, size_t operand_count,
 					void *user_data);
 
-unsigned int avctp_add_state_cb(struct btd_device *dev, avctp_state_cb cb,
-							void *user_data);
-gboolean avctp_remove_state_cb(unsigned int id);
+typedef void (*avctp_destroy_cb_t) (void *user_data);
 
-int avctp_register(struct btd_adapter *adapter, gboolean master);
-void avctp_unregister(struct btd_adapter *adapter);
+struct avctp *avctp_new(int fd, size_t imtu, size_t omtu, uint16_t version);
+int avctp_init_uinput(struct avctp *session, const char *name,
+							const char *address);
+int avctp_connect_browsing(struct avctp *session, int fd, size_t imtu,
+								size_t omtu);
 
-struct avctp *avctp_connect(struct btd_device *device);
-struct avctp *avctp_get(struct btd_device *device);
-bool avctp_is_initiator(struct avctp *session);
-int avctp_connect_browsing(struct avctp *session);
-void avctp_disconnect(struct avctp *session);
+void avctp_shutdown(struct avctp *session);
 
 unsigned int avctp_register_passthrough_handler(struct avctp *session,
 						avctp_passthrough_cb cb,
 						void *user_data);
-bool avctp_unregister_passthrough_handler(unsigned int id);
+bool avctp_unregister_passthrough_handler(struct avctp *session,
+							unsigned int id);
 
 unsigned int avctp_register_pdu_handler(struct avctp *session, uint8_t opcode,
 						avctp_control_pdu_cb cb,
 						void *user_data);
-gboolean avctp_unregister_pdu_handler(unsigned int id);
+bool avctp_unregister_pdu_handler(struct avctp *session, unsigned int id);
 
 unsigned int avctp_register_browsing_pdu_handler(struct avctp *session,
 						avctp_browsing_pdu_cb cb,
 						void *user_data,
-						GDestroyNotify destroy);
-gboolean avctp_unregister_browsing_pdu_handler(unsigned int id);
+						avctp_destroy_cb_t destroy);
+bool avctp_unregister_browsing_pdu_handler(struct avctp *session,
+							unsigned int id);
 
 int avctp_send_passthrough(struct avctp *session, uint8_t op);
 int avctp_send_vendordep(struct avctp *session, uint8_t transaction,
-- 
1.8.4.2


^ permalink raw reply related

* [PATCH BlueZ 1/8] android: Add copy of current AVCTP implemention
From: Luiz Augusto von Dentz @ 2014-01-23 16:39 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

These files are not added to any makefile on purpose because they still
have external dependencies.
---
 {profiles/audio => android}/avctp.c | 0
 {profiles/audio => android}/avctp.h | 0
 2 files changed, 0 insertions(+), 0 deletions(-)
 copy {profiles/audio => android}/avctp.c (100%)
 copy {profiles/audio => android}/avctp.h (100%)

diff --git a/profiles/audio/avctp.c b/android/avctp.c
similarity index 100%
copy from profiles/audio/avctp.c
copy to android/avctp.c
diff --git a/profiles/audio/avctp.h b/android/avctp.h
similarity index 100%
copy from profiles/audio/avctp.h
copy to android/avctp.h
-- 
1.8.4.2


^ permalink raw reply

* [PATCH] android/audio: Fix for loading audio lib
From: Lukasz Rymanowski @ 2014-01-23 16:16 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: szymon.janc, Lukasz Rymanowski

Issue visible when haltest loads audio.a2dp.default.so

> HAL E: load:
> module=/home/rymanluk/devel/kitkat/external/bluetooth/bluez/android/.libs/audio.a2dp.default.so
/home/rymanluk/devel/kitkat/external/bluetooth/bluez/android/.libs/audio.a2dp.default.so:
undefined symbol: clock_gettime
hw_get_module_by_class returned -22

---
 android/Makefile.am | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/android/Makefile.am b/android/Makefile.am
index e9d9db1..f85de20 100644
--- a/android/Makefile.am
+++ b/android/Makefile.am
@@ -152,7 +152,7 @@ android_audio_a2dp_default_la_CFLAGS = $(AM_CFLAGS) -I$(srcdir)/android
 android_audio_a2dp_default_la_LIBADD = @SBC_LIBS@
 
 android_audio_a2dp_default_la_LDFLAGS = $(AM_LDFLAGS) -module -avoid-version \
-					-no-undefined -pthread
+					-no-undefined -pthread -lrt
 
 endif
 
-- 
1.8.4


^ permalink raw reply related

* [PATCH 2/2] android/hal-audio: Do not allocate memory if fd < 0
From: Andrei Emeltchenko @ 2014-01-23 15:43 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1390491807-11095-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

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

Fixes memory leak when returning bad fd we still allocate memory which
is not freed in the caller function audio_open_output_stream().
---
 android/hal-audio.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/android/hal-audio.c b/android/hal-audio.c
index 2fbb956..9bbb53d 100644
--- a/android/hal-audio.c
+++ b/android/hal-audio.c
@@ -705,8 +705,7 @@ static int ipc_open_stream_cmd(uint8_t endpoint_id, uint16_t *mtu, int *fd,
 
 	result = audio_ipc_cmd(AUDIO_SERVICE_ID, AUDIO_OP_OPEN_STREAM,
 				sizeof(cmd), &cmd, &rsp_len, rsp, fd);
-
-	if (result == AUDIO_STATUS_SUCCESS) {
+	if (result == AUDIO_STATUS_SUCCESS && *fd >= 0) {
 		size_t buf_len = sizeof(struct audio_preset) +
 					rsp->preset[0].len;
 		*mtu = rsp->mtu;
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH 1/2] android/hal-audio: Check calloc return value
From: Andrei Emeltchenko @ 2014-01-23 15:43 UTC (permalink / raw)
  To: linux-bluetooth

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

calloc() might return NULL and is usually checked for NULL in BlueZ.
---
 android/hal-audio.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/android/hal-audio.c b/android/hal-audio.c
index 4326ccd..2fbb956 100644
--- a/android/hal-audio.c
+++ b/android/hal-audio.c
@@ -320,6 +320,8 @@ static int sbc_codec_init(struct audio_preset *preset, uint16_t mtu,
 	}
 
 	sbc_data = calloc(sizeof(struct sbc_data), 1);
+	if (!sbc_data)
+		return AUDIO_STATUS_FAILED;
 
 	memcpy(&sbc_data->sbc, preset->data, preset->len);
 
-- 
1.8.3.2


^ permalink raw reply related

* Re: [PATCH SBC 1/2] sbc: Add sbc_reinit_a2dp
From: Luiz Augusto von Dentz @ 2014-01-23 15:32 UTC (permalink / raw)
  To: linux-bluetooth@vger.kernel.org
In-Reply-To: <1390479624-5858-1-git-send-email-luiz.dentz@gmail.com>

Hi,

On Thu, Jan 23, 2014 at 2:20 PM, Luiz Augusto von Dentz
<luiz.dentz@gmail.com> wrote:
> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
>
> This adds sbc_reinit_a2dp that can be used to reconfigure a previous
> initialized sbc_t with new A2DP configuration.
> ---
>  sbc/sbc.c | 49 +++++++++++++++++++++++++++++++++++--------------
>  sbc/sbc.h |  2 ++
>  2 files changed, 37 insertions(+), 14 deletions(-)
>
> diff --git a/sbc/sbc.c b/sbc/sbc.c
> index 51bca55..534027e 100644
> --- a/sbc/sbc.c
> +++ b/sbc/sbc.c
> @@ -1087,19 +1087,14 @@ SBC_EXPORT int sbc_init_msbc(sbc_t *sbc, unsigned long flags)
>         return 0;
>  }
>
> -SBC_EXPORT int sbc_init_a2dp(sbc_t *sbc, unsigned long flags,
> +static int sbc_set_a2dp(sbc_t *sbc, unsigned long flags,
>                                         const void *conf, size_t conf_len)
>  {
>         const struct a2dp_sbc *a2dp;
> -       int err;
>
>         if (conf_len != sizeof(*a2dp))
>                 return -EINVAL;
>
> -       err = sbc_init(sbc, flags);
> -       if (err < 0)
> -               return err;
> -
>         a2dp = conf;
>
>         switch (a2dp->frequency) {
> @@ -1116,7 +1111,7 @@ SBC_EXPORT int sbc_init_a2dp(sbc_t *sbc, unsigned long flags,
>                 sbc->frequency = SBC_FREQ_48000;
>                 break;
>         default:
> -               goto failed;
> +               return -EINVAL;
>         }
>
>         switch (a2dp->channel_mode) {
> @@ -1133,7 +1128,7 @@ SBC_EXPORT int sbc_init_a2dp(sbc_t *sbc, unsigned long flags,
>                 sbc->mode = SBC_MODE_JOINT_STEREO;
>                 break;
>         default:
> -               goto failed;
> +               return -EINVAL;
>         }
>
>         switch (a2dp->allocation_method) {
> @@ -1144,7 +1139,7 @@ SBC_EXPORT int sbc_init_a2dp(sbc_t *sbc, unsigned long flags,
>                 sbc->allocation = SBC_AM_LOUDNESS;
>                 break;
>         default:
> -               goto failed;
> +               return -EINVAL;
>         }
>
>         switch (a2dp->subbands) {
> @@ -1155,7 +1150,7 @@ SBC_EXPORT int sbc_init_a2dp(sbc_t *sbc, unsigned long flags,
>                 sbc->subbands = SBC_SB_8;
>                 break;
>         default:
> -               goto failed;
> +               return -EINVAL;
>         }
>
>         switch (a2dp->block_length) {
> @@ -1172,14 +1167,40 @@ SBC_EXPORT int sbc_init_a2dp(sbc_t *sbc, unsigned long flags,
>                 sbc->blocks = SBC_BLK_16;
>                 break;
>         default:
> -               goto failed;
> +               return -EINVAL;
> +       }
> +
> +       return 0;
> +}
> +
> +SBC_EXPORT int sbc_init_a2dp(sbc_t *sbc, unsigned long flags,
> +                                       const void *conf, size_t conf_len)
> +{
> +       int err;
> +
> +       err = sbc_init(sbc, flags);
> +       if (err < 0)
> +               return err;
> +
> +       err = sbc_set_a2dp(sbc, flags, conf, conf_len);
> +       if (err < 0) {
> +               sbc_finish(sbc);
> +               return err;
>         }
>
>         return 0;
> +}
> +
> +int sbc_reinit_a2dp(sbc_t *sbc, unsigned long flags,
> +                                       const void *conf, size_t conf_len)
> +{
> +       int err;
> +
> +       err = sbc_reinit(sbc, flags);
> +       if (err < 0)
> +               return err;
>
> -failed:
> -       sbc_finish(sbc);
> -       return -EINVAL;
> +       return sbc_set_a2dp(sbc, flags, conf, conf_len);
>  }
>
>  SBC_EXPORT ssize_t sbc_parse(sbc_t *sbc, const void *input, size_t input_len)
> diff --git a/sbc/sbc.h b/sbc/sbc.h
> index a542845..d6f123e 100644
> --- a/sbc/sbc.h
> +++ b/sbc/sbc.h
> @@ -87,6 +87,8 @@ int sbc_reinit(sbc_t *sbc, unsigned long flags);
>  int sbc_init_msbc(sbc_t *sbc, unsigned long flags);
>  int sbc_init_a2dp(sbc_t *sbc, unsigned long flags,
>                                         const void *conf, size_t conf_len);
> +int sbc_reinit_a2dp(sbc_t *sbc, unsigned long flags,
> +                                       const void *conf, size_t conf_len);
>
>  ssize_t sbc_parse(sbc_t *sbc, const void *input, size_t input_len);
>
> --
> 1.8.4.2

Pushed.


-- 
Luiz Augusto von Dentz

^ permalink raw reply

* [PATCH] android/a2dp: Free device outside of notify function
From: Andrei Emeltchenko @ 2014-01-23 15:26 UTC (permalink / raw)
  To: linux-bluetooth

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

device_free() was used inside notify_state() function based on parameter
which makes it complex to follow. Change logic so that notify_state()
only notifies and the other code makes device_free().
---
 android/a2dp.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/android/a2dp.c b/android/a2dp.c
index 572e0d1..d043c04 100644
--- a/android/a2dp.c
+++ b/android/a2dp.c
@@ -189,11 +189,6 @@ static void bt_a2dp_notify_state(struct a2dp_device *dev, uint8_t state)
 
 	ipc_send_notif(HAL_SERVICE_ID_A2DP, HAL_EV_A2DP_CONN_STATE, sizeof(ev),
 									&ev);
-
-	if (state != HAL_A2DP_STATE_DISCONNECTED)
-		return;
-
-	a2dp_device_free(dev);
 }
 
 static void bt_audio_notify_state(struct a2dp_setup *setup, uint8_t state)
@@ -221,6 +216,7 @@ static void disconnect_cb(void *user_data)
 	struct a2dp_device *dev = user_data;
 
 	bt_a2dp_notify_state(dev, HAL_A2DP_STATE_DISCONNECTED);
+	a2dp_device_free(dev);
 }
 
 static int sbc_check_config(void *caps, uint8_t caps_len, void *conf,
@@ -460,6 +456,7 @@ static gboolean idle_timeout(gpointer user_data)
 
 	error("avdtp_discover: %s", strerror(-err));
 	bt_a2dp_notify_state(dev, HAL_A2DP_STATE_DISCONNECTED);
+	a2dp_device_free(dev);
 
 	return FALSE;
 }
@@ -474,6 +471,7 @@ static void signaling_connect_cb(GIOChannel *chan, GError *err,
 
 	if (err) {
 		bt_a2dp_notify_state(dev, HAL_A2DP_STATE_DISCONNECTED);
+		a2dp_device_free(dev);
 		error("%s", err->message);
 		return;
 	}
@@ -519,6 +517,7 @@ static void signaling_connect_cb(GIOChannel *chan, GError *err,
 
 failed:
 	bt_a2dp_notify_state(dev, HAL_A2DP_STATE_DISCONNECTED);
+	a2dp_device_free(dev);
 }
 
 static void bt_a2dp_connect(const void *buf, uint16_t len)
@@ -581,6 +580,7 @@ static void bt_a2dp_disconnect(const void *buf, uint16_t len)
 
 	if (dev->io) {
 		bt_a2dp_notify_state(dev, HAL_A2DP_STATE_DISCONNECTED);
+		a2dp_device_free(dev);
 		goto failed;
 	}
 
-- 
1.8.3.2


^ 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