* [PATCHv3 0/8] IPC negative tester
From: Jakub Tyszkowski @ 2014-01-15 12:42 UTC (permalink / raw)
To: linux-bluetooth
Following patchset adds IPC negative tester framework with few test cases
checking IPC's behaviour on daemon side. Expected daemon's behaviour is to
shut down gracefully in case of receiving invalid IPC data.
v2 changes:
* fixed few indentation issues
* fixed missing __attribute__((packed))
* fixed amount of data written for 'malformed data' test case
* fixed opcode for 'invalid service' test case
* added patch(8) with more 'malformed data' cases
v3 changes:
* changed license to GPL
* changed 'ipc-negative-tester' name to 'ipc-tester'
Jakub Tyszkowski (8):
android/ipc-tester: Skeleton for ipc negative tester
android/ipc-tester: Run daemon in separate process
android/ipc-tester: Add IPC initialization
android/ipc-tester: Add daemon shutdown handler
android/ipc-tester: Add sending test data with ipc
android/ipc-tester: Register services
android/ipc-tester: Add basic test cases for IPC's daemon site
androi/ipc-tester: Add more cases for malformed data
.gitignore | 1 +
android/Makefile.am | 17 ++
android/ipc-tester.c | 727 +++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 745 insertions(+)
create mode 100644 android/ipc-tester.c
--
1.8.5.2
^ permalink raw reply
* [PATCH 12/12] android/tester: Add set device DISCTIMEOUT prop fail test case
From: Grzegorz Kolodziejczyk @ 2014-01-15 12:17 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1389788228-32195-1-git-send-email-grzegorz.kolodziejczyk@tieto.com>
This adds set device DISCOVERY TIMEOUT property fail test case.
---
android/android-tester.c | 32 ++++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)
diff --git a/android/android-tester.c b/android/android-tester.c
index 378d319..6f0e962 100644
--- a/android/android-tester.c
+++ b/android/android-tester.c
@@ -1898,6 +1898,25 @@ static const struct generic_data bt_dev_setprop_bondeddev_fail_test = {
.expected_adapter_status = BT_STATUS_FAIL,
};
+static uint32_t remote_setprop_disctimeout_val = 120;
+
+static struct priority_property remote_setprop_disctimeout_props[] = {
+ {
+ .prop.type = BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT,
+ .prop.val = &remote_setprop_disctimeout_val,
+ .prop.len = sizeof(remote_setprop_disctimeout_val),
+ },
+};
+
+static const struct generic_data bt_dev_setprop_disctimeout_fail_test = {
+ .expected_hal_cb.discovery_state_changed_cb =
+ remote_discovery_state_changed_cb,
+ .expected_hal_cb.device_found_cb = remote_setprop_fail_device_found_cb,
+ .expected_cb_count = 3,
+ .expected_properties = remote_setprop_disctimeout_props,
+ .expected_adapter_status = BT_STATUS_FAIL,
+};
+
static bt_callbacks_t bt_callbacks = {
.size = sizeof(bt_callbacks),
.adapter_state_changed_cb = adapter_state_changed_cb,
@@ -2636,6 +2655,14 @@ static void test_dev_setprop_bondeddev_fail(const void *test_data)
data->if_bluetooth->start_discovery();
}
+static void test_dev_setprop_disctimeout_fail(const void *test_data)
+{
+ struct test_data *data = tester_get_data();
+
+ init_test_conditions(data);
+
+ data->if_bluetooth->start_discovery();
+}
/* Test Socket HAL */
static void adapter_socket_state_changed_cb(bt_state_t state)
@@ -3363,6 +3390,11 @@ int main(int argc, char *argv[])
setup_enabled_adapter,
test_dev_setprop_bondeddev_fail, teardown);
+ test_bredrle("Bluetooth Device Set DISCOVERY_TIMEOUT - Fail",
+ &bt_dev_setprop_disctimeout_fail_test,
+ setup_enabled_adapter,
+ test_dev_setprop_disctimeout_fail, teardown);
+
test_bredrle("Socket Init", NULL, setup_socket_interface,
test_dummy, teardown);
--
1.8.5.2
^ permalink raw reply related
* [PATCH 11/12] android/tester: Add set device BONDED_DEV prop fail test case
From: Grzegorz Kolodziejczyk @ 2014-01-15 12:17 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1389788228-32195-1-git-send-email-grzegorz.kolodziejczyk@tieto.com>
This adds set device BONDED DEVICES property fail test case.
---
android/android-tester.c | 35 +++++++++++++++++++++++++++++++++++
1 file changed, 35 insertions(+)
diff --git a/android/android-tester.c b/android/android-tester.c
index e3c39ce..378d319 100644
--- a/android/android-tester.c
+++ b/android/android-tester.c
@@ -1877,6 +1877,27 @@ static const struct generic_data bt_dev_setprop_scanmode_fail_test = {
.expected_adapter_status = BT_STATUS_FAIL,
};
+static bt_bdaddr_t remote_setprop_bondeddev_val = {
+ .address = { 0x00, 0xaa, 0x01, 0x00, 0x00, 0x00 }
+};
+
+static struct priority_property remote_setprop_bondeddev_props[] = {
+ {
+ .prop.type = BT_PROPERTY_ADAPTER_BONDED_DEVICES,
+ .prop.val = &remote_setprop_bondeddev_val,
+ .prop.len = sizeof(remote_setprop_bondeddev_val),
+ },
+};
+
+static const struct generic_data bt_dev_setprop_bondeddev_fail_test = {
+ .expected_hal_cb.discovery_state_changed_cb =
+ remote_discovery_state_changed_cb,
+ .expected_hal_cb.device_found_cb = remote_setprop_fail_device_found_cb,
+ .expected_cb_count = 3,
+ .expected_properties = remote_setprop_bondeddev_props,
+ .expected_adapter_status = BT_STATUS_FAIL,
+};
+
static bt_callbacks_t bt_callbacks = {
.size = sizeof(bt_callbacks),
.adapter_state_changed_cb = adapter_state_changed_cb,
@@ -2606,6 +2627,15 @@ static void test_dev_setprop_scanmode_fail(const void *test_data)
data->if_bluetooth->start_discovery();
}
+static void test_dev_setprop_bondeddev_fail(const void *test_data)
+{
+ struct test_data *data = tester_get_data();
+
+ init_test_conditions(data);
+
+ data->if_bluetooth->start_discovery();
+}
+
/* Test Socket HAL */
static void adapter_socket_state_changed_cb(bt_state_t state)
@@ -3328,6 +3358,11 @@ int main(int argc, char *argv[])
setup_enabled_adapter,
test_dev_setprop_scanmode_fail, teardown);
+ test_bredrle("Bluetooth Device Set BONDED_DEVICES - Fail",
+ &bt_dev_setprop_bondeddev_fail_test,
+ setup_enabled_adapter,
+ test_dev_setprop_bondeddev_fail, teardown);
+
test_bredrle("Socket Init", NULL, setup_socket_interface,
test_dummy, teardown);
--
1.8.5.2
^ permalink raw reply related
* [PATCH 10/12] android/tester: Add set device SCAN_MODE prop fail test case
From: Grzegorz Kolodziejczyk @ 2014-01-15 12:17 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1389788228-32195-1-git-send-email-grzegorz.kolodziejczyk@tieto.com>
This adds set device SCAN MODE property fail test case.
---
android/android-tester.c | 33 +++++++++++++++++++++++++++++++++
1 file changed, 33 insertions(+)
diff --git a/android/android-tester.c b/android/android-tester.c
index 69e477c..e3c39ce 100644
--- a/android/android-tester.c
+++ b/android/android-tester.c
@@ -1858,6 +1858,25 @@ static const struct generic_data bt_dev_setprop_servrec_fail_test = {
.expected_adapter_status = BT_STATUS_FAIL,
};
+static bt_scan_mode_t remote_setprop_scanmode_val = BT_SCAN_MODE_CONNECTABLE;
+
+static struct priority_property remote_setprop_scanmode_props[] = {
+ {
+ .prop.type = BT_PROPERTY_ADAPTER_SCAN_MODE,
+ .prop.val = &remote_setprop_scanmode_val,
+ .prop.len = sizeof(remote_setprop_scanmode_val),
+ },
+};
+
+static const struct generic_data bt_dev_setprop_scanmode_fail_test = {
+ .expected_hal_cb.discovery_state_changed_cb =
+ remote_discovery_state_changed_cb,
+ .expected_hal_cb.device_found_cb = remote_setprop_fail_device_found_cb,
+ .expected_cb_count = 3,
+ .expected_properties = remote_setprop_scanmode_props,
+ .expected_adapter_status = BT_STATUS_FAIL,
+};
+
static bt_callbacks_t bt_callbacks = {
.size = sizeof(bt_callbacks),
.adapter_state_changed_cb = adapter_state_changed_cb,
@@ -2578,6 +2597,15 @@ static void test_dev_setprop_servrec_fail(const void *test_data)
data->if_bluetooth->start_discovery();
}
+static void test_dev_setprop_scanmode_fail(const void *test_data)
+{
+ struct test_data *data = tester_get_data();
+
+ init_test_conditions(data);
+
+ data->if_bluetooth->start_discovery();
+}
+
/* Test Socket HAL */
static void adapter_socket_state_changed_cb(bt_state_t state)
@@ -3295,6 +3323,11 @@ int main(int argc, char *argv[])
setup_enabled_adapter,
test_dev_setprop_servrec_fail, teardown);
+ test_bredrle("Bluetooth Device Set SCAN_MODE - Fail",
+ &bt_dev_setprop_scanmode_fail_test,
+ setup_enabled_adapter,
+ test_dev_setprop_scanmode_fail, teardown);
+
test_bredrle("Socket Init", NULL, setup_socket_interface,
test_dummy, teardown);
--
1.8.5.2
^ permalink raw reply related
* [PATCH 09/12] android/tester: Add set device SERVICE_RECORD prop fail test case
From: Grzegorz Kolodziejczyk @ 2014-01-15 12:17 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1389788228-32195-1-git-send-email-grzegorz.kolodziejczyk@tieto.com>
This adds set device SERVICE RECORD property fail test case.
---
android/android-tester.c | 37 +++++++++++++++++++++++++++++++++++++
1 file changed, 37 insertions(+)
diff --git a/android/android-tester.c b/android/android-tester.c
index 06ed997..69e477c 100644
--- a/android/android-tester.c
+++ b/android/android-tester.c
@@ -1835,6 +1835,29 @@ static const struct generic_data bt_dev_setprop_bdaddr_fail_test = {
.expected_adapter_status = BT_STATUS_FAIL,
};
+static bt_service_record_t remote_setprop_servrec_val = {
+ .uuid = { {0x00} },
+ .channel = 12,
+ .name = "bt_name",
+};
+
+static struct priority_property remote_setprop_servrec_props[] = {
+ {
+ .prop.type = BT_PROPERTY_SERVICE_RECORD,
+ .prop.val = &remote_setprop_servrec_val,
+ .prop.len = sizeof(remote_setprop_servrec_val),
+ },
+};
+
+static const struct generic_data bt_dev_setprop_servrec_fail_test = {
+ .expected_hal_cb.discovery_state_changed_cb =
+ remote_discovery_state_changed_cb,
+ .expected_hal_cb.device_found_cb = remote_setprop_fail_device_found_cb,
+ .expected_cb_count = 3,
+ .expected_properties = remote_setprop_servrec_props,
+ .expected_adapter_status = BT_STATUS_FAIL,
+};
+
static bt_callbacks_t bt_callbacks = {
.size = sizeof(bt_callbacks),
.adapter_state_changed_cb = adapter_state_changed_cb,
@@ -2546,6 +2569,15 @@ static void test_dev_setprop_bdaddr_fail(const void *test_data)
data->if_bluetooth->start_discovery();
}
+static void test_dev_setprop_servrec_fail(const void *test_data)
+{
+ struct test_data *data = tester_get_data();
+
+ init_test_conditions(data);
+
+ data->if_bluetooth->start_discovery();
+}
+
/* Test Socket HAL */
static void adapter_socket_state_changed_cb(bt_state_t state)
@@ -3258,6 +3290,11 @@ int main(int argc, char *argv[])
setup_enabled_adapter,
test_dev_setprop_bdaddr_fail, teardown);
+ test_bredrle("Bluetooth Device Set SERVICE_RECORD - Fail",
+ &bt_dev_setprop_servrec_fail_test,
+ setup_enabled_adapter,
+ test_dev_setprop_servrec_fail, teardown);
+
test_bredrle("Socket Init", NULL, setup_socket_interface,
test_dummy, teardown);
--
1.8.5.2
^ permalink raw reply related
* [PATCH 08/12] android/tester: Add set device BDADDR prop fail test case
From: Grzegorz Kolodziejczyk @ 2014-01-15 12:17 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1389788228-32195-1-git-send-email-grzegorz.kolodziejczyk@tieto.com>
This adds set device BDADDR property fail test case.
---
android/android-tester.c | 35 +++++++++++++++++++++++++++++++++++
1 file changed, 35 insertions(+)
diff --git a/android/android-tester.c b/android/android-tester.c
index 3109966..06ed997 100644
--- a/android/android-tester.c
+++ b/android/android-tester.c
@@ -1814,6 +1814,27 @@ static const struct generic_data bt_dev_setprop_timpestamp_fail_test = {
.expected_adapter_status = BT_STATUS_FAIL,
};
+static bt_bdaddr_t remote_setprop_bdaddr_val = {
+ .address = { 0x00, 0xaa, 0x01, 0x00, 0x00, 0x00 }
+};
+
+static struct priority_property remote_setprop_bdaddr_props[] = {
+ {
+ .prop.type = BT_PROPERTY_BDADDR,
+ .prop.val = &remote_setprop_bdaddr_val,
+ .prop.len = sizeof(remote_setprop_bdaddr_val),
+ },
+};
+
+static const struct generic_data bt_dev_setprop_bdaddr_fail_test = {
+ .expected_hal_cb.discovery_state_changed_cb =
+ remote_discovery_state_changed_cb,
+ .expected_hal_cb.device_found_cb = remote_setprop_fail_device_found_cb,
+ .expected_cb_count = 3,
+ .expected_properties = remote_setprop_bdaddr_props,
+ .expected_adapter_status = BT_STATUS_FAIL,
+};
+
static bt_callbacks_t bt_callbacks = {
.size = sizeof(bt_callbacks),
.adapter_state_changed_cb = adapter_state_changed_cb,
@@ -2516,6 +2537,15 @@ static void test_dev_setprop_timestamp_fail(const void *test_data)
data->if_bluetooth->start_discovery();
}
+static void test_dev_setprop_bdaddr_fail(const void *test_data)
+{
+ struct test_data *data = tester_get_data();
+
+ init_test_conditions(data);
+
+ data->if_bluetooth->start_discovery();
+}
+
/* Test Socket HAL */
static void adapter_socket_state_changed_cb(bt_state_t state)
@@ -3223,6 +3253,11 @@ int main(int argc, char *argv[])
setup_enabled_adapter,
test_dev_setprop_timestamp_fail, teardown);
+ test_bredrle("Bluetooth Device Set BDADDR - Fail",
+ &bt_dev_setprop_bdaddr_fail_test,
+ setup_enabled_adapter,
+ test_dev_setprop_bdaddr_fail, teardown);
+
test_bredrle("Socket Init", NULL, setup_socket_interface,
test_dummy, teardown);
--
1.8.5.2
^ permalink raw reply related
* [PATCH 07/12] android/tester: Add set device TIMESTAMP prop fail test case
From: Grzegorz Kolodziejczyk @ 2014-01-15 12:17 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1389788228-32195-1-git-send-email-grzegorz.kolodziejczyk@tieto.com>
This adds set device TIMESTAMP property fail test case.
---
android/android-tester.c | 33 +++++++++++++++++++++++++++++++++
1 file changed, 33 insertions(+)
diff --git a/android/android-tester.c b/android/android-tester.c
index 81fb1e6..3109966 100644
--- a/android/android-tester.c
+++ b/android/android-tester.c
@@ -1795,6 +1795,25 @@ static const struct generic_data bt_dev_setprop_rssi_fail_test = {
.expected_adapter_status = BT_STATUS_FAIL,
};
+static int32_t remote_setprop_timestamp_val = 0xAB;
+
+static struct priority_property remote_setprop_timestamp_props[] = {
+ {
+ .prop.type = BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP,
+ .prop.val = (&remote_setprop_timestamp_val),
+ .prop.len = sizeof(remote_setprop_timestamp_val),
+ },
+};
+
+static const struct generic_data bt_dev_setprop_timpestamp_fail_test = {
+ .expected_hal_cb.discovery_state_changed_cb =
+ remote_discovery_state_changed_cb,
+ .expected_hal_cb.device_found_cb = remote_setprop_fail_device_found_cb,
+ .expected_cb_count = 3,
+ .expected_properties = remote_setprop_timestamp_props,
+ .expected_adapter_status = BT_STATUS_FAIL,
+};
+
static bt_callbacks_t bt_callbacks = {
.size = sizeof(bt_callbacks),
.adapter_state_changed_cb = adapter_state_changed_cb,
@@ -2488,6 +2507,15 @@ static void test_dev_setprop_rssi_fail(const void *test_data)
data->if_bluetooth->start_discovery();
}
+static void test_dev_setprop_timestamp_fail(const void *test_data)
+{
+ struct test_data *data = tester_get_data();
+
+ init_test_conditions(data);
+
+ data->if_bluetooth->start_discovery();
+}
+
/* Test Socket HAL */
static void adapter_socket_state_changed_cb(bt_state_t state)
@@ -3190,6 +3218,11 @@ int main(int argc, char *argv[])
setup_enabled_adapter,
test_dev_setprop_rssi_fail, teardown);
+ test_bredrle("Bluetooth Device Set TIMESTAMP - Fail",
+ &bt_dev_setprop_timpestamp_fail_test,
+ setup_enabled_adapter,
+ test_dev_setprop_timestamp_fail, teardown);
+
test_bredrle("Socket Init", NULL, setup_socket_interface,
test_dummy, teardown);
--
1.8.5.2
^ permalink raw reply related
* [PATCH 06/12] android/tester: Add set device RSSI prop fail test case
From: Grzegorz Kolodziejczyk @ 2014-01-15 12:17 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1389788228-32195-1-git-send-email-grzegorz.kolodziejczyk@tieto.com>
This adds set device RSSI property fail test case.
---
android/android-tester.c | 33 +++++++++++++++++++++++++++++++++
1 file changed, 33 insertions(+)
diff --git a/android/android-tester.c b/android/android-tester.c
index ecf0594..81fb1e6 100644
--- a/android/android-tester.c
+++ b/android/android-tester.c
@@ -1776,6 +1776,25 @@ static const struct generic_data bt_dev_setprop_tod_fail_test = {
.expected_adapter_status = BT_STATUS_FAIL,
};
+static int32_t remote_setprop_rssi_val = -60;
+
+static struct priority_property remote_setprop_rssi_props[] = {
+ {
+ .prop.type = BT_PROPERTY_REMOTE_RSSI,
+ .prop.val = &remote_setprop_rssi_val,
+ .prop.len = sizeof(remote_setprop_rssi_val),
+ },
+};
+
+static const struct generic_data bt_dev_setprop_rssi_fail_test = {
+ .expected_hal_cb.discovery_state_changed_cb =
+ remote_discovery_state_changed_cb,
+ .expected_hal_cb.device_found_cb = remote_setprop_fail_device_found_cb,
+ .expected_cb_count = 3,
+ .expected_properties = remote_setprop_rssi_props,
+ .expected_adapter_status = BT_STATUS_FAIL,
+};
+
static bt_callbacks_t bt_callbacks = {
.size = sizeof(bt_callbacks),
.adapter_state_changed_cb = adapter_state_changed_cb,
@@ -2460,6 +2479,15 @@ static void test_dev_setprop_tod_fail(const void *test_data)
data->if_bluetooth->start_discovery();
}
+static void test_dev_setprop_rssi_fail(const void *test_data)
+{
+ struct test_data *data = tester_get_data();
+
+ init_test_conditions(data);
+
+ data->if_bluetooth->start_discovery();
+}
+
/* Test Socket HAL */
static void adapter_socket_state_changed_cb(bt_state_t state)
@@ -3157,6 +3185,11 @@ int main(int argc, char *argv[])
setup_enabled_adapter,
test_dev_setprop_tod_fail, teardown);
+ test_bredrle("Bluetooth Device Set RSSI - Fail",
+ &bt_dev_setprop_rssi_fail_test,
+ setup_enabled_adapter,
+ test_dev_setprop_rssi_fail, teardown);
+
test_bredrle("Socket Init", NULL, setup_socket_interface,
test_dummy, teardown);
--
1.8.5.2
^ permalink raw reply related
* [PATCH 05/12] android/tester: Add set device TOD prop fail test case
From: Grzegorz Kolodziejczyk @ 2014-01-15 12:17 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1389788228-32195-1-git-send-email-grzegorz.kolodziejczyk@tieto.com>
This adds set device TYPE OF DEVICE property fail test case.
---
android/android-tester.c | 33 +++++++++++++++++++++++++++++++++
1 file changed, 33 insertions(+)
diff --git a/android/android-tester.c b/android/android-tester.c
index c4b9cd2..ecf0594 100644
--- a/android/android-tester.c
+++ b/android/android-tester.c
@@ -1757,6 +1757,25 @@ static const struct generic_data bt_dev_setprop_cod_fail_test = {
.expected_adapter_status = BT_STATUS_FAIL,
};
+static bt_device_type_t remote_setprop_tod_val = BT_DEVICE_DEVTYPE_BREDR;
+
+static struct priority_property remote_setprop_tod_props[] = {
+ {
+ .prop.type = BT_PROPERTY_TYPE_OF_DEVICE,
+ .prop.val = &remote_setprop_tod_val,
+ .prop.len = sizeof(remote_setprop_tod_val),
+ },
+};
+
+static const struct generic_data bt_dev_setprop_tod_fail_test = {
+ .expected_hal_cb.discovery_state_changed_cb =
+ remote_discovery_state_changed_cb,
+ .expected_hal_cb.device_found_cb = remote_setprop_fail_device_found_cb,
+ .expected_cb_count = 3,
+ .expected_properties = remote_setprop_tod_props,
+ .expected_adapter_status = BT_STATUS_FAIL,
+};
+
static bt_callbacks_t bt_callbacks = {
.size = sizeof(bt_callbacks),
.adapter_state_changed_cb = adapter_state_changed_cb,
@@ -2432,6 +2451,15 @@ static void test_dev_setprop_cod_fail(const void *test_data)
data->if_bluetooth->start_discovery();
}
+static void test_dev_setprop_tod_fail(const void *test_data)
+{
+ struct test_data *data = tester_get_data();
+
+ init_test_conditions(data);
+
+ data->if_bluetooth->start_discovery();
+}
+
/* Test Socket HAL */
static void adapter_socket_state_changed_cb(bt_state_t state)
@@ -3124,6 +3152,11 @@ int main(int argc, char *argv[])
setup_enabled_adapter,
test_dev_setprop_cod_fail, teardown);
+ test_bredrle("Bluetooth Device Set TOD - Fail",
+ &bt_dev_setprop_tod_fail_test,
+ setup_enabled_adapter,
+ test_dev_setprop_tod_fail, teardown);
+
test_bredrle("Socket Init", NULL, setup_socket_interface,
test_dummy, teardown);
--
1.8.5.2
^ permalink raw reply related
* [PATCH 04/12] android/tester: Add set device COD prop fail test case
From: Grzegorz Kolodziejczyk @ 2014-01-15 12:17 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1389788228-32195-1-git-send-email-grzegorz.kolodziejczyk@tieto.com>
This adds set device CLASS OF DEVICE property fail test case.
---
android/android-tester.c | 33 +++++++++++++++++++++++++++++++++
1 file changed, 33 insertions(+)
diff --git a/android/android-tester.c b/android/android-tester.c
index 2974207..c4b9cd2 100644
--- a/android/android-tester.c
+++ b/android/android-tester.c
@@ -1738,6 +1738,25 @@ static const struct generic_data bt_dev_setprop_uuids_fail_test = {
.expected_adapter_status = BT_STATUS_FAIL,
};
+static uint32_t remote_setprop_cod_val = 0;
+
+static struct priority_property remote_setprop_cod_props[] = {
+ {
+ .prop.type = BT_PROPERTY_CLASS_OF_DEVICE,
+ .prop.val = &remote_setprop_cod_val,
+ .prop.len = sizeof(remote_setprop_cod_val),
+ },
+};
+
+static const struct generic_data bt_dev_setprop_cod_fail_test = {
+ .expected_hal_cb.discovery_state_changed_cb =
+ remote_discovery_state_changed_cb,
+ .expected_hal_cb.device_found_cb = remote_setprop_fail_device_found_cb,
+ .expected_cb_count = 3,
+ .expected_properties = remote_setprop_cod_props,
+ .expected_adapter_status = BT_STATUS_FAIL,
+};
+
static bt_callbacks_t bt_callbacks = {
.size = sizeof(bt_callbacks),
.adapter_state_changed_cb = adapter_state_changed_cb,
@@ -2404,6 +2423,15 @@ static void test_dev_setprop_uuids_fail(const void *test_data)
data->if_bluetooth->start_discovery();
}
+static void test_dev_setprop_cod_fail(const void *test_data)
+{
+ struct test_data *data = tester_get_data();
+
+ init_test_conditions(data);
+
+ data->if_bluetooth->start_discovery();
+}
+
/* Test Socket HAL */
static void adapter_socket_state_changed_cb(bt_state_t state)
@@ -3091,6 +3119,11 @@ int main(int argc, char *argv[])
setup_enabled_adapter,
test_dev_setprop_uuids_fail, teardown);
+ test_bredrle("Bluetooth Device Set COD - Fail",
+ &bt_dev_setprop_cod_fail_test,
+ setup_enabled_adapter,
+ test_dev_setprop_cod_fail, teardown);
+
test_bredrle("Socket Init", NULL, setup_socket_interface,
test_dummy, teardown);
--
1.8.5.2
^ permalink raw reply related
* [PATCH 03/12] android/tester: Add set device UUIDS prop fail test case
From: Grzegorz Kolodziejczyk @ 2014-01-15 12:16 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1389788228-32195-1-git-send-email-grzegorz.kolodziejczyk@tieto.com>
This adds set device UUIDS property fail test case.
---
android/android-tester.c | 31 +++++++++++++++++++++++++++++++
1 file changed, 31 insertions(+)
diff --git a/android/android-tester.c b/android/android-tester.c
index 60371e4..2974207 100644
--- a/android/android-tester.c
+++ b/android/android-tester.c
@@ -1721,6 +1721,23 @@ static const struct generic_data bt_dev_setprop_bdname_fail_test = {
.expected_adapter_status = BT_STATUS_FAIL,
};
+static struct priority_property remote_setprop_uuids_props[] = {
+ {
+ .prop.type = BT_PROPERTY_UUIDS,
+ .prop.val = NULL,
+ .prop.len = 0,
+ },
+};
+
+static const struct generic_data bt_dev_setprop_uuids_fail_test = {
+ .expected_hal_cb.discovery_state_changed_cb =
+ remote_discovery_state_changed_cb,
+ .expected_hal_cb.device_found_cb = remote_setprop_fail_device_found_cb,
+ .expected_cb_count = 3,
+ .expected_properties = remote_setprop_uuids_props,
+ .expected_adapter_status = BT_STATUS_FAIL,
+};
+
static bt_callbacks_t bt_callbacks = {
.size = sizeof(bt_callbacks),
.adapter_state_changed_cb = adapter_state_changed_cb,
@@ -2378,6 +2395,15 @@ static void test_dev_setprop_bdname_fail(const void *test_data)
data->if_bluetooth->start_discovery();
}
+static void test_dev_setprop_uuids_fail(const void *test_data)
+{
+ struct test_data *data = tester_get_data();
+
+ init_test_conditions(data);
+
+ data->if_bluetooth->start_discovery();
+}
+
/* Test Socket HAL */
static void adapter_socket_state_changed_cb(bt_state_t state)
@@ -3060,6 +3086,11 @@ int main(int argc, char *argv[])
setup_enabled_adapter,
test_dev_setprop_bdname_fail, teardown);
+ test_bredrle("Bluetooth Device Set UUIDS - Fail",
+ &bt_dev_setprop_uuids_fail_test,
+ setup_enabled_adapter,
+ test_dev_setprop_uuids_fail, teardown);
+
test_bredrle("Socket Init", NULL, setup_socket_interface,
test_dummy, teardown);
--
1.8.5.2
^ permalink raw reply related
* [PATCH 02/12] android/tester: Add set device BDNAME prop fail test case
From: Grzegorz Kolodziejczyk @ 2014-01-15 12:16 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1389788228-32195-1-git-send-email-grzegorz.kolodziejczyk@tieto.com>
This adds set device BDNAME property fail test case.
---
android/android-tester.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 54 insertions(+)
diff --git a/android/android-tester.c b/android/android-tester.c
index 27f436f..60371e4 100644
--- a/android/android-tester.c
+++ b/android/android-tester.c
@@ -793,6 +793,27 @@ static void remote_setprop_device_found_cb(int num_properties,
check_expected_status(status);
}
+static void remote_setprop_fail_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;
+ bt_status_t status;
+ uint8_t *bdaddr = (uint8_t *)hciemu_get_client_bdaddr(data->hciemu);
+ bt_bdaddr_t remote_addr;
+
+ const bt_property_t prop = test->expected_properties[0].prop;
+
+ bdaddr2android((const bdaddr_t *)bdaddr, &remote_addr.address);
+
+ if (data->cb_count == 2)
+ data->cb_count--;
+
+ status = data->if_bluetooth->set_remote_device_property(&remote_addr,
+ &prop);
+ check_expected_status(status);
+}
+
static void device_found_cb(int num_properties, bt_property_t *properties)
{
struct test_data *data = tester_get_data();
@@ -1681,6 +1702,25 @@ static const struct generic_data bt_dev_setprop_fname_success_test = {
.expected_adapter_status = BT_STATUS_SUCCESS,
};
+static const char remote_setprop_bdname_val[] = "setprop_bdname_fail";
+
+static struct priority_property remote_setprop_bdname_props[] = {
+ {
+ .prop.type = BT_PROPERTY_BDNAME,
+ .prop.val = &remote_setprop_bdname_val,
+ .prop.len = sizeof(remote_setprop_bdname_val) - 1,
+ },
+};
+
+static const struct generic_data bt_dev_setprop_bdname_fail_test = {
+ .expected_hal_cb.discovery_state_changed_cb =
+ remote_discovery_state_changed_cb,
+ .expected_hal_cb.device_found_cb = remote_setprop_fail_device_found_cb,
+ .expected_cb_count = 3,
+ .expected_properties = remote_setprop_bdname_props,
+ .expected_adapter_status = BT_STATUS_FAIL,
+};
+
static bt_callbacks_t bt_callbacks = {
.size = sizeof(bt_callbacks),
.adapter_state_changed_cb = adapter_state_changed_cb,
@@ -2329,6 +2369,15 @@ static void test_dev_setprop_fname_success(const void *test_data)
data->if_bluetooth->start_discovery();
}
+static void test_dev_setprop_bdname_fail(const void *test_data)
+{
+ struct test_data *data = tester_get_data();
+
+ init_test_conditions(data);
+
+ data->if_bluetooth->start_discovery();
+}
+
/* Test Socket HAL */
static void adapter_socket_state_changed_cb(bt_state_t state)
@@ -3006,6 +3055,11 @@ int main(int argc, char *argv[])
setup_enabled_adapter,
test_dev_setprop_fname_success, teardown);
+ test_bredrle("Bluetooth Device Set BDNAME - Fail",
+ &bt_dev_setprop_bdname_fail_test,
+ setup_enabled_adapter,
+ test_dev_setprop_bdname_fail, teardown);
+
test_bredrle("Socket Init", NULL, setup_socket_interface,
test_dummy, teardown);
--
1.8.5.2
^ permalink raw reply related
* [PATCH 01/12] android/tester: Add set device FRIENDLY_NAME prop success test case
From: Grzegorz Kolodziejczyk @ 2014-01-15 12:16 UTC (permalink / raw)
To: linux-bluetooth
This adds set device FRIENDLY NAME property success test case.
---
android/android-tester.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 99 insertions(+)
diff --git a/android/android-tester.c b/android/android-tester.c
index 030111b..27f436f 100644
--- a/android/android-tester.c
+++ b/android/android-tester.c
@@ -653,6 +653,20 @@ static void remote_discovery_state_changed_cb(bt_discovery_state_t state)
}
}
+static void remote_setprop_disc_state_changed_cb(bt_discovery_state_t state)
+{
+ struct test_data *data = tester_get_data();
+
+ if (state == BT_DISCOVERY_STARTED && data->cb_count == 4) {
+ data->cb_count--;
+ return;
+ }
+ if (state == BT_DISCOVERY_STOPPED) {
+ data->cb_count--;
+ check_cb_count();
+ }
+}
+
static void discovery_state_changed_cb(bt_discovery_state_t state)
{
struct test_data *data = tester_get_data();
@@ -758,6 +772,27 @@ static void remote_get_property_device_found_cb(int num_properties,
check_expected_status(status);
}
+static void remote_setprop_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;
+ bt_status_t status;
+ uint8_t *bdaddr = (uint8_t *)hciemu_get_client_bdaddr(data->hciemu);
+ bt_bdaddr_t remote_addr;
+
+ const bt_property_t prop = test->expected_properties[0].prop;
+
+ bdaddr2android((const bdaddr_t *)bdaddr, &remote_addr.address);
+
+ if (data->cb_count == 3)
+ data->cb_count--;
+
+ status = data->if_bluetooth->set_remote_device_property(&remote_addr,
+ &prop);
+ check_expected_status(status);
+}
+
static void device_found_cb(int num_properties, bt_property_t *properties)
{
struct test_data *data = tester_get_data();
@@ -803,6 +838,29 @@ static void remote_test_device_properties_cb(bt_status_t status,
check_expected_property(properties[i]);
}
+static void remote_setprop_device_properties_cb(bt_status_t status,
+ bt_bdaddr_t *bd_addr, int num_properties,
+ bt_property_t *properties)
+{
+ int i;
+ struct test_data *data = tester_get_data();
+ const struct generic_data *test = data->test_data;
+ uint8_t *bdaddr = (uint8_t *)hciemu_get_client_bdaddr(data->hciemu);
+ bt_bdaddr_t remote_addr;
+ const bt_property_t prop = test->expected_properties[1].prop;
+
+ for (i = 0; i < num_properties; i++)
+ check_expected_property(properties[i]);
+
+ if (g_slist_length(data->expected_properties_list) == 1) {
+ bdaddr2android((const bdaddr_t *)bdaddr, &remote_addr.address);
+ data->cb_count--;
+ check_cb_count();
+ data->if_bluetooth->get_remote_device_property(&remote_addr,
+ prop.type);
+ }
+}
+
static void remote_device_properties_cb(bt_status_t status,
bt_bdaddr_t *bd_addr, int num_properties,
bt_property_t *properties)
@@ -1596,6 +1654,33 @@ static const struct generic_data bt_dev_getprop_fname_fail_test = {
.expected_adapter_status = BT_STATUS_FAIL,
};
+static const char remote_setprop_fname_val[] = "set_fname_test";
+
+static struct priority_property remote_setprop_fname_props[] = {
+ {
+ .prop.type = BT_PROPERTY_REMOTE_FRIENDLY_NAME,
+ .prop.val = &remote_setprop_fname_val,
+ .prop.len = sizeof(remote_setprop_fname_val) - 1,
+ },
+ {
+ .prop.type = BT_PROPERTY_REMOTE_FRIENDLY_NAME,
+ .prop.val = &remote_setprop_fname_val,
+ .prop.len = sizeof(remote_setprop_fname_val) - 1,
+ },
+};
+
+static const struct generic_data bt_dev_setprop_fname_success_test = {
+ .expected_hal_cb.discovery_state_changed_cb =
+ remote_setprop_disc_state_changed_cb,
+ .expected_hal_cb.device_found_cb = remote_setprop_device_found_cb,
+ .expected_hal_cb.remote_device_properties_cb =
+ remote_setprop_device_properties_cb,
+ .expected_cb_count = 4,
+ .expected_properties_num = 2,
+ .expected_properties = remote_setprop_fname_props,
+ .expected_adapter_status = BT_STATUS_SUCCESS,
+};
+
static bt_callbacks_t bt_callbacks = {
.size = sizeof(bt_callbacks),
.adapter_state_changed_cb = adapter_state_changed_cb,
@@ -2235,6 +2320,15 @@ static void test_dev_getprop_fname_fail(const void *test_data)
data->if_bluetooth->start_discovery();
}
+static void test_dev_setprop_fname_success(const void *test_data)
+{
+ struct test_data *data = tester_get_data();
+
+ init_test_conditions(data);
+
+ data->if_bluetooth->start_discovery();
+}
+
/* Test Socket HAL */
static void adapter_socket_state_changed_cb(bt_state_t state)
@@ -2907,6 +3001,11 @@ int main(int argc, char *argv[])
setup_enabled_adapter,
test_dev_getprop_fname_fail, teardown);
+ test_bredrle("Bluetooth Device Set FRIENDLY_NAME - Success",
+ &bt_dev_setprop_fname_success_test,
+ setup_enabled_adapter,
+ test_dev_setprop_fname_success, teardown);
+
test_bredrle("Socket Init", NULL, setup_socket_interface,
test_dummy, teardown);
--
1.8.5.2
^ permalink raw reply related
* Re: [PATCH 02/10] android/hal-audio: Add support to register audio endpoints
From: Luiz Augusto von Dentz @ 2014-01-15 10:47 UTC (permalink / raw)
To: Andrzej Kaczmarek; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <1389779996-9749-3-git-send-email-andrzej.kaczmarek@tieto.com>
Hi Andrzej,
On Wed, Jan 15, 2014 at 11:59 AM, Andrzej Kaczmarek
<andrzej.kaczmarek@tieto.com> wrote:
> This patch adds support to register audio enpoints via Audio IPC.
> Endpoints are registered based on predefined codecs table and for
> each defined codec one endpoint is registered. By default, only
> SBC will be supported.
> ---
> android/hal-audio.c | 167 ++++++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 167 insertions(+)
>
> diff --git a/android/hal-audio.c b/android/hal-audio.c
> index 354c3cf..84e7348 100644
> --- a/android/hal-audio.c
> +++ b/android/hal-audio.c
> @@ -31,6 +31,11 @@
> #include "audio-msg.h"
> #include "hal-log.h"
> #include "hal-msg.h"
> +#include "../profiles/audio/a2dp-codecs.h"
> +
> +static const uint8_t a2dp_src_uuid[] = {
> + 0x00, 0x00, 0x11, 0x0a, 0x00, 0x00, 0x10, 0x00,
> + 0x80, 0x00, 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb };
>
> static int listen_sk = -1;
> static int audio_sk = -1;
> @@ -40,11 +45,118 @@ static pthread_t ipc_th = 0;
> static pthread_mutex_t close_mutex = PTHREAD_MUTEX_INITIALIZER;
> static pthread_mutex_t sk_mutex = PTHREAD_MUTEX_INITIALIZER;
>
> +struct audio_input_config {
> + uint32_t rate;
> + uint32_t channels;
> + audio_format_t format;
> +};
> +
> +static int codec_sbc_get_presets(struct audio_preset *preset, size_t *len);
> +
> +struct audio_codec {
> + uint8_t type;
> +
> + int (*get_presets) (struct audio_preset *preset, size_t *len);
> +
> + int (*init) (struct audio_preset *preset, void **codec_data);
> + int (*cleanup) (void *codec_data);
> + int (*get_config) (void *codec_data,
> + struct audio_input_config *config);
> + ssize_t (*write_data) (void *codec_data, const void *buffer,
> + size_t bytes);
> +};
> +
> +static const struct audio_codec audio_codecs[] = {
> + {
> + .type = A2DP_CODEC_SBC,
> +
> + .get_presets = codec_sbc_get_presets,
> + }
> +};
> +
> +#define NUM_CODECS (sizeof(audio_codecs) / sizeof(audio_codecs[0]))
> +
> +#define MAX_AUDIO_ENDPOINTS NUM_CODECS
> +
> +struct audio_endpoint {
> + uint8_t id;
> + const struct audio_codec *codec;
> + void *codec_data;
> + int fd;
> +};
> +
> +static struct audio_endpoint audio_endpoints[MAX_AUDIO_ENDPOINTS];
> +
> struct a2dp_audio_dev {
> struct audio_hw_device dev;
> struct audio_stream_out *out;
> };
>
> +static const a2dp_sbc_t codec_sbc_presets[] = {
Call it sbc_presets
> + {
> + .frequency = SBC_SAMPLING_FREQ_44100 | SBC_SAMPLING_FREQ_48000,
> + .channel_mode = SBC_CHANNEL_MODE_MONO |
> + SBC_CHANNEL_MODE_DUAL_CHANNEL |
> + SBC_CHANNEL_MODE_STEREO |
> + SBC_CHANNEL_MODE_JOINT_STEREO,
> + .subbands = SBC_SUBBANDS_4 | SBC_SUBBANDS_8,
> + .allocation_method = SBC_ALLOCATION_SNR |
> + SBC_ALLOCATION_LOUDNESS,
> + .block_length = SBC_BLOCK_LENGTH_4 | SBC_BLOCK_LENGTH_8 |
> + SBC_BLOCK_LENGTH_12 | SBC_BLOCK_LENGTH_16,
> + .min_bitpool = MIN_BITPOOL,
> + .max_bitpool = MAX_BITPOOL
> + },
> + {
> + .frequency = SBC_SAMPLING_FREQ_44100,
> + .channel_mode = SBC_CHANNEL_MODE_STEREO,
> + .subbands = SBC_SUBBANDS_8,
> + .allocation_method = SBC_ALLOCATION_LOUDNESS,
> + .block_length = SBC_BLOCK_LENGTH_16,
> + .min_bitpool = MIN_BITPOOL,
> + .max_bitpool = MAX_BITPOOL
> + },
> + {
> + .frequency = SBC_SAMPLING_FREQ_48000,
> + .channel_mode = SBC_CHANNEL_MODE_STEREO,
> + .subbands = SBC_SUBBANDS_8,
> + .allocation_method = SBC_ALLOCATION_LOUDNESS,
> + .block_length = SBC_BLOCK_LENGTH_16,
> + .min_bitpool = MIN_BITPOOL,
> + .max_bitpool = MAX_BITPOOL
> + },
> +};
Perhaps we should add the recomended values from A2DP spec, iirc there
are at least 3 preset recommended there, high, medium, low quality.
> +static int codec_sbc_get_presets(struct audio_preset *preset, size_t *len)
> +{
Call this one sbc_get_presets
> + int i;
> + int count;
> + size_t new_len = 0;
> + uint8_t *ptr = (uint8_t *) preset;
> + size_t preset_size = sizeof(*preset) + sizeof(a2dp_sbc_t);
> +
> + DBG("");
> +
> + count = sizeof(codec_sbc_presets) / sizeof(codec_sbc_presets[0]);
> +
> + for (i = 0; i < count; i++) {
> + preset = (struct audio_preset *) ptr;
> +
> + if (new_len + preset_size > *len)
> + break;
> +
> + preset->len = sizeof(a2dp_sbc_t);
> + memcpy(preset->data, &codec_sbc_presets[i], preset->len);
> +
> + new_len += preset_size;
> + ptr += preset_size;
> + }
> +
> + *len = new_len;
> +
> + return i;
> +}
> +
> static void audio_ipc_cleanup(void)
> {
> if (audio_sk >= 0) {
> @@ -200,6 +312,54 @@ failed:
> return AUDIO_STATUS_FAILED;
> }
>
> +static int ipc_open_cmd(const struct audio_codec *codec)
> +{
> + uint8_t buf[BLUEZ_AUDIO_MTU];
> + struct audio_cmd_open *cmd = (struct audio_cmd_open *) buf;
> + struct audio_rsp_open rsp;
> + size_t cmd_len = sizeof(buf) - sizeof(*cmd);
> + size_t rsp_len = sizeof(rsp);
> + int result;
> +
> + DBG("");
> +
> + memcpy(cmd->uuid, a2dp_src_uuid, sizeof(a2dp_src_uuid));
> +
> + cmd->codec = codec->type;
> + cmd->presets = codec->get_presets(cmd->preset, &cmd_len);
> +
> + cmd_len += sizeof(*cmd);
> +
> + result = audio_ipc_cmd(AUDIO_SERVICE_ID, AUDIO_OP_OPEN, cmd_len, cmd,
> + &rsp_len, &rsp, NULL);
> +
> + if (result != AUDIO_STATUS_SUCCESS)
> + return 0;
> +
> + return rsp.id;
> +}
> +
> +static int register_endpoints(void)
> +{
> + struct audio_endpoint *ep = &audio_endpoints[0];
> + size_t i;
> +
> + for (i = 0; i < NUM_CODECS; i++) {
> + const struct audio_codec *codec = &audio_codecs[i];
> +
> + ep->id = ipc_open_cmd(codec);
> +
> + if (!ep->id)
> + return AUDIO_STATUS_FAILED;
> +
> + ep->codec = codec;
> + ep->codec_data = NULL;
> + ep->fd = -1;
> + }
This seems to be overwriting ep if there is more than one codec
available, I guess you need to move ep within the loop as well then
you assign the correspondent codec index to the endpoint index.
--
Luiz Augusto von Dentz
^ permalink raw reply
* [PATCH 09/10] android/hal-audio: Fix module loading
From: Andrzej Kaczmarek @ 2014-01-15 9:59 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Andrzej Kaczmarek
In-Reply-To: <1389779996-9749-1-git-send-email-andrzej.kaczmarek@tieto.com>
---
android/hal-audio.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/android/hal-audio.c b/android/hal-audio.c
index 640a32c..68651a8 100644
--- a/android/hal-audio.c
+++ b/android/hal-audio.c
@@ -937,7 +937,7 @@ static char *audio_get_parameters(const struct audio_hw_device *dev,
static int audio_init_check(const struct audio_hw_device *dev)
{
DBG("");
- return -ENOSYS;
+ return 0;
}
static int audio_set_voice_volume(struct audio_hw_device *dev, float volume)
@@ -1174,6 +1174,7 @@ static int audio_open(const hw_module_t *module, const char *name,
if (!a2dp_dev)
return -ENOMEM;
+ a2dp_dev->dev.common.tag = HARDWARE_DEVICE_TAG;
a2dp_dev->dev.common.version = AUDIO_DEVICE_API_VERSION_CURRENT;
a2dp_dev->dev.common.module = (struct hw_module_t *) module;
a2dp_dev->dev.common.close = audio_close;
--
1.8.5.2
^ permalink raw reply related
* [PATCH 08/10] android/hal-audio: Handle audio preset from stream
From: Andrzej Kaczmarek @ 2014-01-15 9:59 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Andrzej Kaczmarek
In-Reply-To: <1389779996-9749-1-git-send-email-andrzej.kaczmarek@tieto.com>
This patch adds handling of audio preset received after stream is
opened. Preset is used to initialize codec and then to set input
configuration so audio subsystem can write data in a format that
codec can handle later.
---
android/hal-audio.c | 108 +++++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 102 insertions(+), 6 deletions(-)
diff --git a/android/hal-audio.c b/android/hal-audio.c
index 224c3d1..640a32c 100644
--- a/android/hal-audio.c
+++ b/android/hal-audio.c
@@ -51,7 +51,15 @@ struct audio_input_config {
audio_format_t format;
};
+struct codec_sbc_data {
+ a2dp_sbc_t sbc;
+};
+
static int codec_sbc_get_presets(struct audio_preset *preset, size_t *len);
+static int codec_sbc_init(struct audio_preset *preset, void **codec_data);
+static int codec_sbc_cleanup(void *codec_data);
+static int codec_sbc_get_config(void *codec_data,
+ struct audio_input_config *config);
struct audio_codec {
uint8_t type;
@@ -71,6 +79,10 @@ static const struct audio_codec audio_codecs[] = {
.type = A2DP_CODEC_SBC,
.get_presets = codec_sbc_get_presets,
+
+ .init = codec_sbc_init,
+ .cleanup = codec_sbc_cleanup,
+ .get_config = codec_sbc_get_config,
}
};
@@ -99,6 +111,7 @@ struct a2dp_stream_out {
struct audio_endpoint *ep;
enum a2dp_state_t audio_state;
+ struct audio_input_config cfg;
};
struct a2dp_audio_dev {
@@ -171,6 +184,64 @@ static int codec_sbc_get_presets(struct audio_preset *preset, size_t *len)
return i;
}
+static int codec_sbc_init(struct audio_preset *preset, void **codec_data)
+{
+ struct codec_sbc_data *sbc_data;
+
+ DBG("");
+
+ if (preset->len != sizeof(a2dp_sbc_t)) {
+ DBG("preset size mismatch");
+ return AUDIO_STATUS_FAILED;
+ }
+
+ sbc_data = calloc(sizeof(struct codec_sbc_data), 1);
+
+ memcpy(&sbc_data->sbc, preset->data, preset->len);
+
+ *codec_data = sbc_data;
+
+ return AUDIO_STATUS_SUCCESS;
+}
+
+static int codec_sbc_cleanup(void *codec_data)
+{
+ DBG("");
+
+ free(codec_data);
+
+ return AUDIO_STATUS_SUCCESS;
+}
+
+static int codec_sbc_get_config(void *codec_data,
+ struct audio_input_config *config)
+{
+ struct codec_sbc_data *sbc_data = (struct codec_sbc_data *) codec_data;
+
+ switch (sbc_data->sbc.frequency) {
+ case SBC_SAMPLING_FREQ_16000:
+ config->rate = 16000;
+ break;
+ case SBC_SAMPLING_FREQ_32000:
+ config->rate = 32000;
+ break;
+ case SBC_SAMPLING_FREQ_44100:
+ config->rate = 44100;
+ break;
+ case SBC_SAMPLING_FREQ_48000:
+ config->rate = 48000;
+ break;
+ default:
+ return AUDIO_STATUS_FAILED;
+ }
+ config->channels = sbc_data->sbc.channel_mode == SBC_CHANNEL_MODE_MONO ?
+ AUDIO_CHANNEL_OUT_MONO :
+ AUDIO_CHANNEL_OUT_STEREO;
+ config->format = AUDIO_FORMAT_PCM_16_BIT;
+
+ return AUDIO_STATUS_SUCCESS;
+}
+
static void audio_ipc_cleanup(void)
{
if (audio_sk >= 0) {
@@ -507,14 +578,25 @@ static ssize_t out_write(struct audio_stream_out *stream, const void *buffer,
static uint32_t out_get_sample_rate(const struct audio_stream *stream)
{
+ struct a2dp_stream_out *out = (struct a2dp_stream_out *) stream;
+
DBG("");
- return -ENOSYS;
+
+ return out->cfg.rate;
}
static int out_set_sample_rate(struct audio_stream *stream, uint32_t rate)
{
+ struct a2dp_stream_out *out = (struct a2dp_stream_out *) stream;
+
DBG("");
- return -ENOSYS;
+
+ if (rate != out->cfg.rate) {
+ DBG("cannot set sample rate to %d", rate);
+ return -1;
+ }
+
+ return 0;
}
static size_t out_get_buffer_size(const struct audio_stream *stream)
@@ -525,14 +607,20 @@ static size_t out_get_buffer_size(const struct audio_stream *stream)
static uint32_t out_get_channels(const struct audio_stream *stream)
{
+ struct a2dp_stream_out *out = (struct a2dp_stream_out *) stream;
+
DBG("");
- return -ENOSYS;
+
+ return out->cfg.channels;
}
static audio_format_t out_get_format(const struct audio_stream *stream)
{
+ struct a2dp_stream_out *out = (struct a2dp_stream_out *) stream;
+
DBG("");
- return -ENOSYS;
+
+ return out->cfg.format;
}
static int out_set_format(struct audio_stream *stream, audio_format_t format)
@@ -758,6 +846,7 @@ static int audio_open_output_stream(struct audio_hw_device *dev,
struct a2dp_audio_dev *a2dp_dev = (struct a2dp_audio_dev *) dev;
struct a2dp_stream_out *out;
struct audio_preset *preset;
+ const struct audio_codec *codec;
out = calloc(1, sizeof(struct a2dp_stream_out));
if (!out)
@@ -791,7 +880,13 @@ static int audio_open_output_stream(struct audio_hw_device *dev,
if (!preset)
goto fail;
- /* TODO: initialize codec using received audio_preset */
+ codec = out->ep->codec;
+
+ codec->init(preset, &out->ep->codec_data);
+ codec->get_config(out->ep->codec_data, &out->cfg);
+
+ DBG("rate=%d channels=%d format=%d", out->cfg.rate,
+ out->cfg.channels, out->cfg.format);
free(preset);
@@ -818,7 +913,8 @@ static void audio_close_output_stream(struct audio_hw_device *dev,
ipc_close_stream_cmd(ep->id);
- /* TODO: cleanup codec */
+ ep->codec->cleanup(ep->codec_data);
+ ep->codec_data = NULL;
free(stream);
a2dp_dev->out = NULL;
--
1.8.5.2
^ permalink raw reply related
* [PATCH 07/10] android/hal-audio: Add support to suspend output stream
From: Andrzej Kaczmarek @ 2014-01-15 9:59 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Andrzej Kaczmarek
In-Reply-To: <1389779996-9749-1-git-send-email-andrzej.kaczmarek@tieto.com>
This patch adds support to suspend output stream via Audio IPC.
>From HAL perspective stream can be either in standby or suspended -
the former is default one and can be auto-resumed on write while the
latter cannot be resumed only after explicitly going into standby
on audio code request.
---
android/hal-audio.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 70 insertions(+), 3 deletions(-)
diff --git a/android/hal-audio.c b/android/hal-audio.c
index 3c799e3..224c3d1 100644
--- a/android/hal-audio.c
+++ b/android/hal-audio.c
@@ -430,6 +430,21 @@ static int ipc_resume_stream_cmd(uint8_t endpoint_id)
return result;
}
+static int ipc_suspend_stream_cmd(uint8_t endpoint_id)
+{
+ struct audio_cmd_suspend_stream cmd;
+ int result;
+
+ DBG("");
+
+ cmd.id = endpoint_id;
+
+ result = audio_ipc_cmd(AUDIO_SERVICE_ID, AUDIO_OP_SUSPEND_STREAM,
+ sizeof(cmd), &cmd, NULL, NULL, NULL);
+
+ return result;
+}
+
static int register_endpoints(void)
{
struct audio_endpoint *ep = &audio_endpoints[0];
@@ -528,8 +543,17 @@ static int out_set_format(struct audio_stream *stream, audio_format_t format)
static int out_standby(struct audio_stream *stream)
{
+ struct a2dp_stream_out *out = (struct a2dp_stream_out *) stream;
+
DBG("");
- return -ENOSYS;
+
+ if (out->audio_state == AUDIO_A2DP_STATE_STARTED) {
+ if (ipc_suspend_stream_cmd(out->ep->id) != AUDIO_STATUS_SUCCESS)
+ return -1;
+ out->audio_state = AUDIO_A2DP_STATE_STANDBY;
+ }
+
+ return 0;
}
static int out_dump(const struct audio_stream *stream, int fd)
@@ -540,8 +564,51 @@ static int out_dump(const struct audio_stream *stream, int fd)
static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
{
- DBG("");
- return -ENOSYS;
+ struct a2dp_stream_out *out = (struct a2dp_stream_out *) stream;
+ char *kvpair;
+ char *str;
+ char *saveptr;
+ bool enter_suspend = false;
+ bool exit_suspend = false;
+
+ DBG("%s", kvpairs);
+
+ str = strdup(kvpairs);
+ kvpair = strtok_r(str, ";", &saveptr);
+
+ for (; kvpair && *kvpair; kvpair = strtok_r(NULL, ";", &saveptr)) {
+ char *keyval;
+
+ keyval = strchr(kvpair, '=');
+ if (!keyval)
+ continue;
+
+ *keyval = '\0';
+ keyval++;
+
+ if (!strcmp(kvpair, "closing")) {
+ if (!strcmp(keyval, "true"))
+ out->audio_state = AUDIO_A2DP_STATE_NONE;
+ } else if (!strcmp(kvpair, "A2dpSuspended")) {
+ if (!strcmp(keyval, "true"))
+ enter_suspend = true;
+ else
+ exit_suspend = true;
+ }
+ }
+
+ free(str);
+
+ if (enter_suspend && out->audio_state == AUDIO_A2DP_STATE_STARTED) {
+ if (ipc_suspend_stream_cmd(out->ep->id) != AUDIO_STATUS_SUCCESS)
+ return -1;
+ out->audio_state = AUDIO_A2DP_STATE_SUSPENDED;
+ }
+
+ if (exit_suspend && out->audio_state == AUDIO_A2DP_STATE_SUSPENDED)
+ out->audio_state = AUDIO_A2DP_STATE_STANDBY;
+
+ return 0;
}
static char *out_get_parameters(const struct audio_stream *stream,
--
1.8.5.2
^ permalink raw reply related
* [PATCH 06/10] android/hal-audio: Add support to resume output stream
From: Andrzej Kaczmarek @ 2014-01-15 9:59 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Andrzej Kaczmarek
In-Reply-To: <1389779996-9749-1-git-send-email-andrzej.kaczmarek@tieto.com>
This patch adds support to resume output stream via Audio IPC.
Stream is automatically resumed on first write when stream is in
standby state.
---
android/hal-audio.c | 37 +++++++++++++++++++++++++++++++++++--
1 file changed, 35 insertions(+), 2 deletions(-)
diff --git a/android/hal-audio.c b/android/hal-audio.c
index ebb742c..3c799e3 100644
--- a/android/hal-audio.c
+++ b/android/hal-audio.c
@@ -415,6 +415,21 @@ static int ipc_close_stream_cmd(uint8_t endpoint_id)
return result;
}
+static int ipc_resume_stream_cmd(uint8_t endpoint_id)
+{
+ struct audio_cmd_resume_stream cmd;
+ int result;
+
+ DBG("");
+
+ cmd.id = endpoint_id;
+
+ result = audio_ipc_cmd(AUDIO_SERVICE_ID, AUDIO_OP_RESUME_STREAM,
+ sizeof(cmd), &cmd, NULL, NULL, NULL);
+
+ return result;
+}
+
static int register_endpoints(void)
{
struct audio_endpoint *ep = &audio_endpoints[0];
@@ -453,8 +468,26 @@ static void unregister_endpoints(void)
static ssize_t out_write(struct audio_stream_out *stream, const void *buffer,
size_t bytes)
{
- DBG("");
- return -ENOSYS;
+ struct a2dp_stream_out *out = (struct a2dp_stream_out *) stream;
+
+ /* We can auto-start only from standby */
+ if (out->audio_state == AUDIO_A2DP_STATE_STANDBY) {
+ DBG("stream in standby, auto-start");
+
+ if (ipc_resume_stream_cmd(out->ep->id) != AUDIO_STATUS_SUCCESS)
+ return -1;
+
+ out->audio_state = AUDIO_A2DP_STATE_STARTED;
+ }
+
+ if (out->audio_state != AUDIO_A2DP_STATE_STARTED) {
+ DBG("stream not started");
+ return -1;
+ }
+
+ /* TODO: encode data using codec */
+
+ return bytes;
}
static uint32_t out_get_sample_rate(const struct audio_stream *stream)
--
1.8.5.2
^ permalink raw reply related
* [PATCH 05/10] android/hal-audio: Add support to close output stream
From: Andrzej Kaczmarek @ 2014-01-15 9:59 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Andrzej Kaczmarek
In-Reply-To: <1389779996-9749-1-git-send-email-andrzej.kaczmarek@tieto.com>
---
android/hal-audio.c | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/android/hal-audio.c b/android/hal-audio.c
index 2ced954..ebb742c 100644
--- a/android/hal-audio.c
+++ b/android/hal-audio.c
@@ -400,6 +400,21 @@ static int ipc_open_stream_cmd(uint8_t endpoint_id,
return result;
}
+static int ipc_close_stream_cmd(uint8_t endpoint_id)
+{
+ struct audio_cmd_close_stream cmd;
+ int result;
+
+ DBG("");
+
+ cmd.id = endpoint_id;
+
+ result = audio_ipc_cmd(AUDIO_SERVICE_ID, AUDIO_OP_CLOSE_STREAM,
+ sizeof(cmd), &cmd, NULL, NULL, NULL);
+
+ return result;
+}
+
static int register_endpoints(void)
{
struct audio_endpoint *ep = &audio_endpoints[0];
@@ -697,9 +712,14 @@ static void audio_close_output_stream(struct audio_hw_device *dev,
struct audio_stream_out *stream)
{
struct a2dp_audio_dev *a2dp_dev = (struct a2dp_audio_dev *) dev;
+ struct audio_endpoint *ep = a2dp_dev->out->ep;
DBG("");
+ ipc_close_stream_cmd(ep->id);
+
+ /* TODO: cleanup codec */
+
free(stream);
a2dp_dev->out = NULL;
}
--
1.8.5.2
^ permalink raw reply related
* [PATCH 04/10] android/hal-audio: Add support to open output stream
From: Andrzej Kaczmarek @ 2014-01-15 9:59 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Andrzej Kaczmarek
In-Reply-To: <1389779996-9749-1-git-send-email-andrzej.kaczmarek@tieto.com>
This patch adds support to open output stream via Audio IPC.
Since only SBC is supported, we always try to open stream for first
endpoint only which is enough.
---
android/hal-audio.c | 109 ++++++++++++++++++++++++++++++++++++++++++----------
1 file changed, 88 insertions(+), 21 deletions(-)
diff --git a/android/hal-audio.c b/android/hal-audio.c
index 3b4648a..2ced954 100644
--- a/android/hal-audio.c
+++ b/android/hal-audio.c
@@ -87,9 +87,23 @@ struct audio_endpoint {
static struct audio_endpoint audio_endpoints[MAX_AUDIO_ENDPOINTS];
+enum a2dp_state_t {
+ AUDIO_A2DP_STATE_NONE,
+ AUDIO_A2DP_STATE_STANDBY,
+ AUDIO_A2DP_STATE_SUSPENDED,
+ AUDIO_A2DP_STATE_STARTED
+};
+
+struct a2dp_stream_out {
+ struct audio_stream_out stream;
+
+ struct audio_endpoint *ep;
+ enum a2dp_state_t audio_state;
+};
+
struct a2dp_audio_dev {
struct audio_hw_device dev;
- struct audio_stream_out *out;
+ struct a2dp_stream_out *out;
};
static const a2dp_sbc_t codec_sbc_presets[] = {
@@ -354,6 +368,38 @@ static int ipc_close_cmd(uint8_t endpoint_id)
return result;
}
+static int ipc_open_stream_cmd(uint8_t endpoint_id,
+ struct audio_preset **caps)
+{
+ char buf[BLUEZ_AUDIO_MTU];
+ struct audio_cmd_open_stream cmd;
+ struct audio_rsp_open_stream *rsp =
+ (struct audio_rsp_open_stream *) &buf;
+ size_t rsp_len = sizeof(buf);
+ int result;
+
+ DBG("");
+
+ if (!caps)
+ return AUDIO_STATUS_FAILED;
+
+ cmd.id = endpoint_id;
+
+ result = audio_ipc_cmd(AUDIO_SERVICE_ID, AUDIO_OP_OPEN_STREAM,
+ sizeof(cmd), &cmd, &rsp_len, rsp, NULL);
+
+ if (result == AUDIO_STATUS_SUCCESS) {
+ size_t buf_len = sizeof(struct audio_preset) +
+ rsp->preset[0].len;
+ *caps = malloc(buf_len);
+ memcpy(*caps, &rsp->preset, buf_len);
+ } else {
+ *caps = NULL;
+ }
+
+ return result;
+}
+
static int register_endpoints(void)
{
struct audio_endpoint *ep = &audio_endpoints[0];
@@ -595,35 +641,56 @@ static int audio_open_output_stream(struct audio_hw_device *dev,
{
struct a2dp_audio_dev *a2dp_dev = (struct a2dp_audio_dev *) dev;
- struct audio_stream_out *out;
+ struct a2dp_stream_out *out;
+ struct audio_preset *preset;
- out = calloc(1, sizeof(struct audio_stream_out));
+ out = calloc(1, sizeof(struct a2dp_stream_out));
if (!out)
return -ENOMEM;
DBG("");
- out->common.get_sample_rate = out_get_sample_rate;
- out->common.set_sample_rate = out_set_sample_rate;
- out->common.get_buffer_size = out_get_buffer_size;
- out->common.get_channels = out_get_channels;
- out->common.get_format = out_get_format;
- out->common.set_format = out_set_format;
- out->common.standby = out_standby;
- out->common.dump = out_dump;
- out->common.set_parameters = out_set_parameters;
- out->common.get_parameters = out_get_parameters;
- out->common.add_audio_effect = out_add_audio_effect;
- out->common.remove_audio_effect = out_remove_audio_effect;
- out->get_latency = out_get_latency;
- out->set_volume = out_set_volume;
- out->write = out_write;
- out->get_render_position = out_get_render_position;
-
- *stream_out = out;
+ out->stream.common.get_sample_rate = out_get_sample_rate;
+ out->stream.common.set_sample_rate = out_set_sample_rate;
+ out->stream.common.get_buffer_size = out_get_buffer_size;
+ out->stream.common.get_channels = out_get_channels;
+ out->stream.common.get_format = out_get_format;
+ out->stream.common.set_format = out_set_format;
+ out->stream.common.standby = out_standby;
+ out->stream.common.dump = out_dump;
+ out->stream.common.set_parameters = out_set_parameters;
+ out->stream.common.get_parameters = out_get_parameters;
+ out->stream.common.add_audio_effect = out_add_audio_effect;
+ out->stream.common.remove_audio_effect = out_remove_audio_effect;
+ out->stream.get_latency = out_get_latency;
+ out->stream.set_volume = out_set_volume;
+ out->stream.write = out_write;
+ out->stream.get_render_position = out_get_render_position;
+
+ /* TODO: for now we always use endpoint 0 */
+ out->ep = &audio_endpoints[0];
+
+ if (ipc_open_stream_cmd(out->ep->id, &preset) != AUDIO_STATUS_SUCCESS)
+ goto fail;
+
+ if (!preset)
+ goto fail;
+
+ /* TODO: initialize codec using received audio_preset */
+
+ free(preset);
+
+ *stream_out = &out->stream;
a2dp_dev->out = out;
+ out->audio_state = AUDIO_A2DP_STATE_STANDBY;
+
return 0;
+
+fail:
+ free(out);
+ *stream_out = NULL;
+ return -EIO;
}
static void audio_close_output_stream(struct audio_hw_device *dev,
--
1.8.5.2
^ permalink raw reply related
* [PATCH 03/10] android/hal-audio: Add support to unregister audio endpoints
From: Andrzej Kaczmarek @ 2014-01-15 9:59 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Andrzej Kaczmarek
In-Reply-To: <1389779996-9749-1-git-send-email-andrzej.kaczmarek@tieto.com>
---
android/hal-audio.c | 33 +++++++++++++++++++++++++++++++++
1 file changed, 33 insertions(+)
diff --git a/android/hal-audio.c b/android/hal-audio.c
index 84e7348..3b4648a 100644
--- a/android/hal-audio.c
+++ b/android/hal-audio.c
@@ -339,6 +339,21 @@ static int ipc_open_cmd(const struct audio_codec *codec)
return rsp.id;
}
+static int ipc_close_cmd(uint8_t endpoint_id)
+{
+ struct audio_cmd_close cmd;
+ int result;
+
+ DBG("");
+
+ cmd.id = endpoint_id;
+
+ result = audio_ipc_cmd(AUDIO_SERVICE_ID, AUDIO_OP_CLOSE,
+ sizeof(cmd), &cmd, NULL, NULL, NULL);
+
+ return result;
+}
+
static int register_endpoints(void)
{
struct audio_endpoint *ep = &audio_endpoints[0];
@@ -360,6 +375,20 @@ static int register_endpoints(void)
return AUDIO_STATUS_SUCCESS;
}
+static void unregister_endpoints(void)
+{
+ size_t i;
+
+ for (i = 0; i < MAX_AUDIO_ENDPOINTS; i++) {
+ struct audio_endpoint *ep = &audio_endpoints[i];
+
+ if (ep->id) {
+ ipc_close_cmd(ep->id);
+ memset(ep, 0, sizeof(*ep));
+ }
+ }
+}
+
static ssize_t out_write(struct audio_stream_out *stream, const void *buffer,
size_t bytes)
{
@@ -755,6 +784,8 @@ static void *ipc_handler(void *data)
if (register_endpoints() != AUDIO_STATUS_SUCCESS) {
error("audio: Failed to register endpoints");
+ unregister_endpoints();
+
shutdown(audio_sk, SHUT_RDWR);
continue;
}
@@ -778,6 +809,8 @@ static void *ipc_handler(void *data)
pthread_mutex_unlock(&close_mutex);
}
+ unregister_endpoints();
+
info("Closing Audio IPC thread");
return NULL;
}
--
1.8.5.2
^ permalink raw reply related
* [PATCH 02/10] android/hal-audio: Add support to register audio endpoints
From: Andrzej Kaczmarek @ 2014-01-15 9:59 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Andrzej Kaczmarek
In-Reply-To: <1389779996-9749-1-git-send-email-andrzej.kaczmarek@tieto.com>
This patch adds support to register audio enpoints via Audio IPC.
Endpoints are registered based on predefined codecs table and for
each defined codec one endpoint is registered. By default, only
SBC will be supported.
---
android/hal-audio.c | 167 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 167 insertions(+)
diff --git a/android/hal-audio.c b/android/hal-audio.c
index 354c3cf..84e7348 100644
--- a/android/hal-audio.c
+++ b/android/hal-audio.c
@@ -31,6 +31,11 @@
#include "audio-msg.h"
#include "hal-log.h"
#include "hal-msg.h"
+#include "../profiles/audio/a2dp-codecs.h"
+
+static const uint8_t a2dp_src_uuid[] = {
+ 0x00, 0x00, 0x11, 0x0a, 0x00, 0x00, 0x10, 0x00,
+ 0x80, 0x00, 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb };
static int listen_sk = -1;
static int audio_sk = -1;
@@ -40,11 +45,118 @@ static pthread_t ipc_th = 0;
static pthread_mutex_t close_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t sk_mutex = PTHREAD_MUTEX_INITIALIZER;
+struct audio_input_config {
+ uint32_t rate;
+ uint32_t channels;
+ audio_format_t format;
+};
+
+static int codec_sbc_get_presets(struct audio_preset *preset, size_t *len);
+
+struct audio_codec {
+ uint8_t type;
+
+ int (*get_presets) (struct audio_preset *preset, size_t *len);
+
+ int (*init) (struct audio_preset *preset, void **codec_data);
+ int (*cleanup) (void *codec_data);
+ int (*get_config) (void *codec_data,
+ struct audio_input_config *config);
+ ssize_t (*write_data) (void *codec_data, const void *buffer,
+ size_t bytes);
+};
+
+static const struct audio_codec audio_codecs[] = {
+ {
+ .type = A2DP_CODEC_SBC,
+
+ .get_presets = codec_sbc_get_presets,
+ }
+};
+
+#define NUM_CODECS (sizeof(audio_codecs) / sizeof(audio_codecs[0]))
+
+#define MAX_AUDIO_ENDPOINTS NUM_CODECS
+
+struct audio_endpoint {
+ uint8_t id;
+ const struct audio_codec *codec;
+ void *codec_data;
+ int fd;
+};
+
+static struct audio_endpoint audio_endpoints[MAX_AUDIO_ENDPOINTS];
+
struct a2dp_audio_dev {
struct audio_hw_device dev;
struct audio_stream_out *out;
};
+static const a2dp_sbc_t codec_sbc_presets[] = {
+ {
+ .frequency = SBC_SAMPLING_FREQ_44100 | SBC_SAMPLING_FREQ_48000,
+ .channel_mode = SBC_CHANNEL_MODE_MONO |
+ SBC_CHANNEL_MODE_DUAL_CHANNEL |
+ SBC_CHANNEL_MODE_STEREO |
+ SBC_CHANNEL_MODE_JOINT_STEREO,
+ .subbands = SBC_SUBBANDS_4 | SBC_SUBBANDS_8,
+ .allocation_method = SBC_ALLOCATION_SNR |
+ SBC_ALLOCATION_LOUDNESS,
+ .block_length = SBC_BLOCK_LENGTH_4 | SBC_BLOCK_LENGTH_8 |
+ SBC_BLOCK_LENGTH_12 | SBC_BLOCK_LENGTH_16,
+ .min_bitpool = MIN_BITPOOL,
+ .max_bitpool = MAX_BITPOOL
+ },
+ {
+ .frequency = SBC_SAMPLING_FREQ_44100,
+ .channel_mode = SBC_CHANNEL_MODE_STEREO,
+ .subbands = SBC_SUBBANDS_8,
+ .allocation_method = SBC_ALLOCATION_LOUDNESS,
+ .block_length = SBC_BLOCK_LENGTH_16,
+ .min_bitpool = MIN_BITPOOL,
+ .max_bitpool = MAX_BITPOOL
+ },
+ {
+ .frequency = SBC_SAMPLING_FREQ_48000,
+ .channel_mode = SBC_CHANNEL_MODE_STEREO,
+ .subbands = SBC_SUBBANDS_8,
+ .allocation_method = SBC_ALLOCATION_LOUDNESS,
+ .block_length = SBC_BLOCK_LENGTH_16,
+ .min_bitpool = MIN_BITPOOL,
+ .max_bitpool = MAX_BITPOOL
+ },
+};
+
+static int codec_sbc_get_presets(struct audio_preset *preset, size_t *len)
+{
+ int i;
+ int count;
+ size_t new_len = 0;
+ uint8_t *ptr = (uint8_t *) preset;
+ size_t preset_size = sizeof(*preset) + sizeof(a2dp_sbc_t);
+
+ DBG("");
+
+ count = sizeof(codec_sbc_presets) / sizeof(codec_sbc_presets[0]);
+
+ for (i = 0; i < count; i++) {
+ preset = (struct audio_preset *) ptr;
+
+ if (new_len + preset_size > *len)
+ break;
+
+ preset->len = sizeof(a2dp_sbc_t);
+ memcpy(preset->data, &codec_sbc_presets[i], preset->len);
+
+ new_len += preset_size;
+ ptr += preset_size;
+ }
+
+ *len = new_len;
+
+ return i;
+}
+
static void audio_ipc_cleanup(void)
{
if (audio_sk >= 0) {
@@ -200,6 +312,54 @@ failed:
return AUDIO_STATUS_FAILED;
}
+static int ipc_open_cmd(const struct audio_codec *codec)
+{
+ uint8_t buf[BLUEZ_AUDIO_MTU];
+ struct audio_cmd_open *cmd = (struct audio_cmd_open *) buf;
+ struct audio_rsp_open rsp;
+ size_t cmd_len = sizeof(buf) - sizeof(*cmd);
+ size_t rsp_len = sizeof(rsp);
+ int result;
+
+ DBG("");
+
+ memcpy(cmd->uuid, a2dp_src_uuid, sizeof(a2dp_src_uuid));
+
+ cmd->codec = codec->type;
+ cmd->presets = codec->get_presets(cmd->preset, &cmd_len);
+
+ cmd_len += sizeof(*cmd);
+
+ result = audio_ipc_cmd(AUDIO_SERVICE_ID, AUDIO_OP_OPEN, cmd_len, cmd,
+ &rsp_len, &rsp, NULL);
+
+ if (result != AUDIO_STATUS_SUCCESS)
+ return 0;
+
+ return rsp.id;
+}
+
+static int register_endpoints(void)
+{
+ struct audio_endpoint *ep = &audio_endpoints[0];
+ size_t i;
+
+ for (i = 0; i < NUM_CODECS; i++) {
+ const struct audio_codec *codec = &audio_codecs[i];
+
+ ep->id = ipc_open_cmd(codec);
+
+ if (!ep->id)
+ return AUDIO_STATUS_FAILED;
+
+ ep->codec = codec;
+ ep->codec_data = NULL;
+ ep->fd = -1;
+ }
+
+ return AUDIO_STATUS_SUCCESS;
+}
+
static ssize_t out_write(struct audio_stream_out *stream, const void *buffer,
size_t bytes)
{
@@ -592,6 +752,13 @@ static void *ipc_handler(void *data)
DBG("Audio IPC: Connected");
+ if (register_endpoints() != AUDIO_STATUS_SUCCESS) {
+ error("audio: Failed to register endpoints");
+
+ shutdown(audio_sk, SHUT_RDWR);
+ continue;
+ }
+
memset(&pfd, 0, sizeof(pfd));
pfd.fd = audio_sk;
pfd.events = POLLHUP | POLLERR | POLLNVAL;
--
1.8.5.2
^ permalink raw reply related
* [PATCH 01/10] android/hal-audio: Add audio_ipc_cmd
From: Andrzej Kaczmarek @ 2014-01-15 9:59 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Lukasz Rymanowski
In-Reply-To: <1389779996-9749-1-git-send-email-andrzej.kaczmarek@tieto.com>
From: Lukasz Rymanowski <lukasz.rymanowski@tieto.com>
Add function to handle send/receive on audio_sk.
---
android/Makefile.am | 1 +
android/hal-audio.c | 149 ++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 150 insertions(+)
diff --git a/android/Makefile.am b/android/Makefile.am
index 7806f79..e09f967 100644
--- a/android/Makefile.am
+++ b/android/Makefile.am
@@ -120,6 +120,7 @@ android_android_tester_LDFLAGS = -pthread -ldl
plugin_LTLIBRARIES += android/audio.a2dp.default.la
android_audio_a2dp_default_la_SOURCES = android/audio-msg.h \
+ android/hal-msg.h \
android/hal-audio.c \
android/hardware/audio.h \
android/hardware/audio_effect.h \
diff --git a/android/hal-audio.c b/android/hal-audio.c
index c51b065..354c3cf 100644
--- a/android/hal-audio.c
+++ b/android/hal-audio.c
@@ -30,6 +30,7 @@
#include "audio-msg.h"
#include "hal-log.h"
+#include "hal-msg.h"
static int listen_sk = -1;
static int audio_sk = -1;
@@ -37,6 +38,7 @@ static bool close_thread = false;
static pthread_t ipc_th = 0;
static pthread_mutex_t close_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t sk_mutex = PTHREAD_MUTEX_INITIALIZER;
struct a2dp_audio_dev {
struct audio_hw_device dev;
@@ -51,6 +53,153 @@ static void audio_ipc_cleanup(void)
}
}
+static int audio_ipc_cmd(uint8_t service_id, uint8_t opcode, uint16_t len,
+ void *param, size_t *rsp_len, void *rsp, int *fd)
+{
+ ssize_t ret;
+ struct msghdr msg;
+ struct iovec iv[2];
+ struct hal_hdr cmd;
+ char cmsgbuf[CMSG_SPACE(sizeof(int))];
+ struct hal_status s;
+ size_t s_len = sizeof(s);
+
+ if (audio_sk < 0) {
+ error("audio: Invalid cmd socket passed to audio_ipc_cmd");
+ goto failed;
+ }
+
+ if (!rsp || !rsp_len) {
+ memset(&s, 0, s_len);
+ rsp_len = &s_len;
+ rsp = &s;
+ }
+
+ memset(&msg, 0, sizeof(msg));
+ memset(&cmd, 0, sizeof(cmd));
+
+ cmd.service_id = service_id;
+ cmd.opcode = opcode;
+ cmd.len = len;
+
+ iv[0].iov_base = &cmd;
+ iv[0].iov_len = sizeof(cmd);
+
+ iv[1].iov_base = param;
+ iv[1].iov_len = len;
+
+ msg.msg_iov = iv;
+ msg.msg_iovlen = 2;
+
+ pthread_mutex_lock(&sk_mutex);
+
+ ret = sendmsg(audio_sk, &msg, 0);
+ if (ret < 0) {
+ error("audio: Sending command failed:%s", strerror(errno));
+ pthread_mutex_unlock(&sk_mutex);
+ goto failed;
+ }
+
+ /* socket was shutdown */
+ if (ret == 0) {
+ error("audio: Command socket closed");
+ goto failed;
+ }
+
+ memset(&msg, 0, sizeof(msg));
+ memset(&cmd, 0, sizeof(cmd));
+
+ iv[0].iov_base = &cmd;
+ iv[0].iov_len = sizeof(cmd);
+
+ iv[1].iov_base = rsp;
+ iv[1].iov_len = *rsp_len;
+
+ msg.msg_iov = iv;
+ msg.msg_iovlen = 2;
+
+ if (fd) {
+ memset(cmsgbuf, 0, sizeof(cmsgbuf));
+ msg.msg_control = cmsgbuf;
+ msg.msg_controllen = sizeof(cmsgbuf);
+ }
+
+ ret = recvmsg(audio_sk, &msg, 0);
+ if (ret < 0) {
+ error("audio: Receiving command response failed:%s",
+ strerror(errno));
+ pthread_mutex_unlock(&sk_mutex);
+ goto failed;
+ }
+
+ pthread_mutex_unlock(&sk_mutex);
+
+ if (ret < (ssize_t) sizeof(cmd)) {
+ error("audio: Too small response received(%zd bytes)", ret);
+ goto failed;
+ }
+
+ if (cmd.service_id != service_id) {
+ error("audio: Invalid service id (%u vs %u)", cmd.service_id,
+ service_id);
+ goto failed;
+ }
+
+ if (ret != (ssize_t) (sizeof(cmd) + cmd.len)) {
+ error("audio: Malformed response received(%zd bytes)", ret);
+ goto failed;
+ }
+
+ if (cmd.opcode != opcode && cmd.opcode != AUDIO_OP_STATUS) {
+ error("audio: Invalid opcode received (%u vs %u)",
+ cmd.opcode, opcode);
+ goto failed;
+ }
+
+ if (cmd.opcode == AUDIO_OP_STATUS) {
+ struct hal_status *s = rsp;
+
+ if (sizeof(*s) != cmd.len) {
+ error("audio: Invalid status length");
+ goto failed;
+ }
+
+ if (s->code == AUDIO_STATUS_SUCCESS) {
+ error("audio: Invalid success status response");
+ goto failed;
+ }
+
+ return s->code;
+ }
+
+ /* Receive auxiliary data in msg */
+ if (fd) {
+ struct cmsghdr *cmsg;
+
+ *fd = -1;
+
+ for (cmsg = CMSG_FIRSTHDR(&msg); cmsg;
+ cmsg = CMSG_NXTHDR(&msg, cmsg)) {
+ if (cmsg->cmsg_level == SOL_SOCKET
+ && cmsg->cmsg_type == SCM_RIGHTS) {
+ memcpy(fd, CMSG_DATA(cmsg), sizeof(int));
+ break;
+ }
+ }
+ }
+
+ if (rsp_len)
+ *rsp_len = cmd.len;
+
+ return AUDIO_STATUS_SUCCESS;
+
+failed:
+ /* Some serious issue happen on IPC - recover */
+ shutdown(audio_sk, SHUT_RDWR);
+ audio_sk = -1;
+ return AUDIO_STATUS_FAILED;
+}
+
static ssize_t out_write(struct audio_stream_out *stream, const void *buffer,
size_t bytes)
{
--
1.8.5.2
^ permalink raw reply related
* [PATCH 00/10] android: Audio HAL implementation
From: Andrzej Kaczmarek @ 2014-01-15 9:59 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Andrzej Kaczmarek
Hi,
Here are patches which implement Audio HAL. Complete IPC signalling is
implemented with stubs to add SBC codec in next step.
Note that in order to make these patches work correctly BlueZ needs to
notify A2DP connected state after streaming channel is connected - at
the moment it does so just after singalling is connected which will
result in an error when Audio HAL tries to open stream.
Andrzej Kaczmarek (9):
android/hal-audio: Add support to register audio endpoints
android/hal-audio: Add support to unregister audio endpoints
android/hal-audio: Add support to open output stream
android/hal-audio: Add support to close output stream
android/hal-audio: Add support to resume output stream
android/hal-audio: Add support to suspend output stream
android/hal-audio: Handle audio preset from stream
android/hal-audio: Fix module loading
android/hal-audio: Fix AudioFlinger crash
Lukasz Rymanowski (1):
android/hal-audio: Add audio_ipc_cmd
android/Makefile.am | 1 +
android/hal-audio.c | 699 +++++++++++++++++++++++++++++++++++++++++++++++++---
2 files changed, 667 insertions(+), 33 deletions(-)
--
1.8.5.2
^ permalink raw reply
* Re: [PATCH 1/2] android/a2dp: Fix IPC response length calculation
From: Luiz Augusto von Dentz @ 2014-01-15 9:38 UTC (permalink / raw)
To: Andrzej Kaczmarek; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <1389716179-21874-1-git-send-email-andrzej.kaczmarek@tieto.com>
Hi Andrzej,
On Tue, Jan 14, 2014 at 6:16 PM, Andrzej Kaczmarek
<andrzej.kaczmarek@tieto.com> wrote:
> struct audio_rsp_open_stream has only zero-length array member thus its
> size equals to 0. We need to explicitly specify size of array element
> type here.
> ---
> android/a2dp.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/android/a2dp.c b/android/a2dp.c
> index 9f3164a..145cd67 100644
> --- a/android/a2dp.c
> +++ b/android/a2dp.c
> @@ -1088,8 +1088,8 @@ static void bt_stream_open(const void *buf, uint16_t len)
> return;
> }
>
> - len = sizeof(*rsp) + setup->preset->len;
> - rsp = g_malloc0(sizeof(*rsp) + setup->preset->len);
> + len = sizeof(struct audio_preset) + setup->preset->len;
> + rsp = g_malloc0(len);
> rsp->preset->len = setup->preset->len;
> memcpy(rsp->preset->data, setup->preset->data, setup->preset->len);
>
> --
> 1.8.5.2
Pushed, thanks.
--
Luiz Augusto von Dentz
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox