* [PATCH 07/11] android/unit: Add another case for variable sized data
From: Jakub Tyszkowski @ 2014-02-04 14:39 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1391524749-2518-1-git-send-email-jakub.tyszkowski@tieto.com>
This patch adds test for variable length data handling. Handlers struct
have static values representing minimum payload. It cannot be predicted
how large data will be sent so they should accept data larger than
declared inside ipc_handler array, which holds the minimum size of such
message.
---
android/test-ipc.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/android/test-ipc.c b/android/test-ipc.c
index 523011e..2120d15 100644
--- a/android/test-ipc.c
+++ b/android/test-ipc.c
@@ -487,6 +487,18 @@ static const struct test_data test_cmd_vardata_valid = {
.handlers_size = 1,
};
+static const struct ipc_handler cmd_vardata_handlers_valid2[] = {
+ { test_cmd_handler_1, true, sizeof(VARDATA_EX1) - 1 }
+};
+
+static const struct test_data test_cmd_vardata_valid_2 = {
+ .cmd = &test_cmd_vardata,
+ .cmd_size = sizeof(struct hal_hdr) + sizeof(VARDATA_EX1),
+ .service = 0,
+ .handlers = cmd_vardata_handlers_valid2,
+ .handlers_size = 1,
+};
+
int main(int argc, char *argv[])
{
g_test_init(&argc, &argv, NULL);
@@ -511,6 +523,9 @@ int main(int argc, char *argv[])
g_test_add_data_func("/android_ipc/test_cmd_vardata_valid",
&test_cmd_vardata_valid,
test_cmd_reg);
+ g_test_add_data_func("/android_ipc/test_cmd_vardata_valid_2",
+ &test_cmd_vardata_valid_2,
+ test_cmd_reg);
return g_test_run();
}
--
1.8.5.2
^ permalink raw reply related
* [PATCH 06/11] android/unit: Add test case for variable sized data
From: Jakub Tyszkowski @ 2014-02-04 14:39 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1391524749-2518-1-git-send-email-jakub.tyszkowski@tieto.com>
Check if sending variable length data with proper msg size declared inside the
header succeeds.
---
android/test-ipc.c | 29 +++++++++++++++++++++++++++++
1 file changed, 29 insertions(+)
diff --git a/android/test-ipc.c b/android/test-ipc.c
index a2d3085..523011e 100644
--- a/android/test-ipc.c
+++ b/android/test-ipc.c
@@ -461,6 +461,32 @@ static const struct test_data test_cmd_opcode_invalid_1 = {
.expected_signal = SIGTERM
};
+#define VARDATA_EX1 "some data example"
+
+struct vardata {
+ struct hal_hdr hdr;
+ uint8_t data[BLUEZ_HAL_MTU - sizeof(struct hal_hdr)];
+} __attribute__((packed));
+
+static const struct vardata test_cmd_vardata = {
+ .hdr.service_id = 0,
+ .hdr.opcode = 1,
+ .hdr.len = sizeof(VARDATA_EX1),
+ .data = VARDATA_EX1,
+};
+
+static const struct ipc_handler cmd_vardata_handlers[] = {
+ { test_cmd_handler_1, true, sizeof(VARDATA_EX1) }
+};
+
+static const struct test_data test_cmd_vardata_valid = {
+ .cmd = &test_cmd_vardata,
+ .cmd_size = sizeof(struct hal_hdr) + sizeof(VARDATA_EX1),
+ .service = 0,
+ .handlers = cmd_vardata_handlers,
+ .handlers_size = 1,
+};
+
int main(int argc, char *argv[])
{
g_test_init(&argc, &argv, NULL);
@@ -482,6 +508,9 @@ int main(int argc, char *argv[])
g_test_add_data_func("/android_ipc/test_cmd_opcode_invalid_1",
&test_cmd_opcode_invalid_1,
test_cmd_reg);
+ g_test_add_data_func("/android_ipc/test_cmd_vardata_valid",
+ &test_cmd_vardata_valid,
+ test_cmd_reg);
return g_test_run();
}
--
1.8.5.2
^ permalink raw reply related
* [PATCH 05/11] android/unit: Add support for variable length data
From: Jakub Tyszkowski @ 2014-02-04 14:39 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1391524749-2518-1-git-send-email-jakub.tyszkowski@tieto.com>
This patch adds sending messages larger than just hal_hdr, and fixes
response verification which worked only for empty messages but was
failing when sending something more than just header.
---
android/test-ipc.c | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/android/test-ipc.c b/android/test-ipc.c
index cb6f518..a2d3085 100644
--- a/android/test-ipc.c
+++ b/android/test-ipc.c
@@ -44,7 +44,7 @@
struct test_data {
uint32_t expected_signal;
- const struct hal_hdr *cmd;
+ const void *cmd;
uint16_t cmd_size;
uint8_t service;
const struct ipc_handler *handlers;
@@ -79,9 +79,16 @@ static gboolean cmd_watch(GIOChannel *io, GIOCondition cond,
{
struct context *context = user_data;
const struct test_data *test_data = context->data;
+ const struct hal_hdr *sent_msg = test_data->cmd;
uint8_t buf[128];
int sk;
+ struct hal_hdr success_resp = {
+ .service_id = sent_msg->service_id,
+ .opcode = sent_msg->opcode,
+ .len = 0,
+ };
+
g_assert(test_data->expected_signal == 0);
if (cond & (G_IO_HUP | G_IO_ERR | G_IO_NVAL)) {
@@ -91,8 +98,8 @@ static gboolean cmd_watch(GIOChannel *io, GIOCondition cond,
sk = g_io_channel_unix_get_fd(io);
- g_assert(read(sk, buf, sizeof(buf)) == test_data->cmd_size);
- g_assert(!memcmp(test_data->cmd, buf, test_data->cmd_size));
+ g_assert(read(sk, buf, sizeof(buf)) == sizeof(struct hal_hdr));
+ g_assert(!memcmp(&success_resp, buf, sizeof(struct hal_hdr)));
context_quit(context);
--
1.8.5.2
^ permalink raw reply related
* [PATCH 04/11] android/unit: Add case for opcode without handler
From: Jakub Tyszkowski @ 2014-02-04 14:39 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1391524749-2518-1-git-send-email-jakub.tyszkowski@tieto.com>
This test case checks if IPC shuts down on unhandled opcode.
---
android/test-ipc.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/android/test-ipc.c b/android/test-ipc.c
index 1e027fa..cb6f518 100644
--- a/android/test-ipc.c
+++ b/android/test-ipc.c
@@ -445,6 +445,15 @@ static const struct test_data test_cmd_opcode_valid_2 = {
.handlers_size = 2,
};
+static const struct test_data test_cmd_opcode_invalid_1 = {
+ .cmd = &test_cmd_2_hdr,
+ .cmd_size = sizeof(test_cmd_2_hdr),
+ .service = 0,
+ .handlers = cmd_handlers,
+ .handlers_size = 1,
+ .expected_signal = SIGTERM
+};
+
int main(int argc, char *argv[])
{
g_test_init(&argc, &argv, NULL);
@@ -463,6 +472,9 @@ int main(int argc, char *argv[])
&test_cmd_opcode_valid_1, test_cmd_reg);
g_test_add_data_func("/android_ipc/test_cmd_opcode_valid_2",
&test_cmd_opcode_valid_2, test_cmd_reg);
+ g_test_add_data_func("/android_ipc/test_cmd_opcode_invalid_1",
+ &test_cmd_opcode_invalid_1,
+ test_cmd_reg);
return g_test_run();
}
--
1.8.5.2
^ permalink raw reply related
* [PATCH 03/11] android/unit: Add test cases for proper handler calls
From: Jakub Tyszkowski @ 2014-02-04 14:39 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1391524749-2518-1-git-send-email-jakub.tyszkowski@tieto.com>
This patch adds tests for calling proper opcode handler. Two handlers
are registered, but one always results in failure. No failure means that
proper opcode <-> handler maching is done by the ipc mechanism.
---
android/test-ipc.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 46 insertions(+)
diff --git a/android/test-ipc.c b/android/test-ipc.c
index 8e31507..1e027fa 100644
--- a/android/test-ipc.c
+++ b/android/test-ipc.c
@@ -368,6 +368,16 @@ static void test_cmd_handler_1(const void *buf, uint16_t len)
ipc_send_rsp(0, 1, 0);
}
+static void test_cmd_handler_2(const void *buf, uint16_t len)
+{
+ ipc_send_rsp(0, 2, 0);
+}
+
+static void test_cmd_handler_invalid(const void *buf, uint16_t len)
+{
+ raise(SIGTERM);
+}
+
static const struct test_data test_init_1 = {};
static const struct hal_hdr test_cmd_1_hdr = {
@@ -376,6 +386,12 @@ static const struct hal_hdr test_cmd_1_hdr = {
.len = 0
};
+static const struct hal_hdr test_cmd_2_hdr = {
+ .service_id = 0,
+ .opcode = 2,
+ .len = 0
+};
+
static const struct test_data test_cmd_service_invalid_1 = {
.cmd = &test_cmd_1_hdr,
.cmd_size = sizeof(test_cmd_1_hdr),
@@ -403,6 +419,32 @@ static const struct test_data test_cmd_service_invalid_2 = {
.expected_signal = SIGTERM
};
+static const struct ipc_handler cmd_handlers_invalid_2[] = {
+ { test_cmd_handler_1, false, 0 },
+ { test_cmd_handler_invalid, false, 0 }
+};
+
+static const struct ipc_handler cmd_handlers_invalid_1[] = {
+ { test_cmd_handler_invalid, false, 0 },
+ { test_cmd_handler_2, false, 0 },
+};
+
+static const struct test_data test_cmd_opcode_valid_1 = {
+ .cmd = &test_cmd_1_hdr,
+ .cmd_size = sizeof(test_cmd_1_hdr),
+ .service = 0,
+ .handlers = cmd_handlers_invalid_2,
+ .handlers_size = 2,
+};
+
+static const struct test_data test_cmd_opcode_valid_2 = {
+ .cmd = &test_cmd_2_hdr,
+ .cmd_size = sizeof(test_cmd_2_hdr),
+ .service = 0,
+ .handlers = cmd_handlers_invalid_1,
+ .handlers_size = 2,
+};
+
int main(int argc, char *argv[])
{
g_test_init(&argc, &argv, NULL);
@@ -417,6 +459,10 @@ int main(int argc, char *argv[])
&test_cmd_service_valid_1, test_cmd_reg);
g_test_add_data_func("/android_ipc/test_cmd_service_invalid_2",
&test_cmd_service_invalid_2, test_cmd_reg_1);
+ g_test_add_data_func("/android_ipc/test_cmd_opcode_valid_1",
+ &test_cmd_opcode_valid_1, test_cmd_reg);
+ g_test_add_data_func("/android_ipc/test_cmd_opcode_valid_2",
+ &test_cmd_opcode_valid_2, test_cmd_reg);
return g_test_run();
}
--
1.8.5.2
^ permalink raw reply related
* [PATCH 02/11] android/unit: Rename cmd handler
From: Jakub Tyszkowski @ 2014-02-04 14:39 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1391524749-2518-1-git-send-email-jakub.tyszkowski@tieto.com>
This handler responses for opcode == 1, thus should use proper naming to
avoid confision when more functions sending different responses will be
added.
---
android/test-ipc.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/android/test-ipc.c b/android/test-ipc.c
index d0f3f6b..8e31507 100644
--- a/android/test-ipc.c
+++ b/android/test-ipc.c
@@ -363,7 +363,7 @@ static void test_cmd_reg_1(gconstpointer data)
ipc_cleanup();
}
-static void test_cmd_handler(const void *buf, uint16_t len)
+static void test_cmd_handler_1(const void *buf, uint16_t len)
{
ipc_send_rsp(0, 1, 0);
}
@@ -383,7 +383,7 @@ static const struct test_data test_cmd_service_invalid_1 = {
};
static const struct ipc_handler cmd_handlers[] = {
- { test_cmd_handler, false, 0 }
+ { test_cmd_handler_1, false, 0 }
};
static const struct test_data test_cmd_service_valid_1 = {
--
1.8.5.2
^ permalink raw reply related
* [PATCH 01/11] android/unit: Fix checking for expected termination
From: Jakub Tyszkowski @ 2014-02-04 14:38 UTC (permalink / raw)
To: linux-bluetooth
This fix makes sure that when signalled termination is expected,
it actually happens. If IPC termination is expected no response will be
sent, so cmd_watch will never be executed. But if it is executed when
expecting termination, its a failure.
---
android/test-ipc.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/android/test-ipc.c b/android/test-ipc.c
index 8af5739..d0f3f6b 100644
--- a/android/test-ipc.c
+++ b/android/test-ipc.c
@@ -82,6 +82,8 @@ static gboolean cmd_watch(GIOChannel *io, GIOCondition cond,
uint8_t buf[128];
int sk;
+ g_assert(test_data->expected_signal == 0);
+
if (cond & (G_IO_HUP | G_IO_ERR | G_IO_NVAL)) {
g_assert(FALSE);
return FALSE;
--
1.8.5.2
^ permalink raw reply related
* Re: [PATCH 3/3] avrcp: Fix possible buffer overflow and correct length
From: Andrei Emeltchenko @ 2014-02-04 14:08 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1391098376-26834-3-git-send-email-Andrei.Emeltchenko.news@gmail.com>
On Thu, Jan 30, 2014 at 06:12:56PM +0200, Andrei Emeltchenko wrote:
> From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
>
> Wrong length was given and it was also possible to crash.
ping
> ---
> profiles/audio/avrcp.c | 6 +++++-
> 1 file changed, 5 insertions(+), 1 deletion(-)
>
> diff --git a/profiles/audio/avrcp.c b/profiles/audio/avrcp.c
> index 128f7d3..f9fce5c 100644
> --- a/profiles/audio/avrcp.c
> +++ b/profiles/audio/avrcp.c
> @@ -1899,8 +1899,12 @@ static void avrcp_get_current_player_value(struct avrcp *session,
> {
> uint8_t buf[AVRCP_HEADER_LENGTH + 5];
> struct avrcp_header *pdu = (void *) buf;
> + uint16_t length = AVRCP_HEADER_LENGTH + count + 1;
> int i;
>
> + if (count + 1 > 5)
> + return;
> +
> memset(buf, 0, sizeof(buf));
>
> set_company_id(pdu->company_id, IEEEID_BTSIG);
> @@ -1913,7 +1917,7 @@ static void avrcp_get_current_player_value(struct avrcp *session,
> pdu->params[i + 1] = attrs[i];
>
> avctp_send_vendordep_req(session->conn, AVC_CTYPE_STATUS,
> - AVC_SUBUNIT_PANEL, buf, sizeof(buf),
> + AVC_SUBUNIT_PANEL, buf, length,
> avrcp_player_value_rsp, session);
> }
>
> --
> 1.8.3.2
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH 2/3] avrcp: Fix using incorrect buffer for SetVolume
From: Andrei Emeltchenko @ 2014-02-04 14:08 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1391098376-26834-2-git-send-email-Andrei.Emeltchenko.news@gmail.com>
On Thu, Jan 30, 2014 at 06:12:55PM +0200, Andrei Emeltchenko wrote:
> From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
>
> The command requires one parameter.
ping
> ---
> profiles/audio/avrcp.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/profiles/audio/avrcp.c b/profiles/audio/avrcp.c
> index 2e1a940..128f7d3 100644
> --- a/profiles/audio/avrcp.c
> +++ b/profiles/audio/avrcp.c
> @@ -3706,7 +3706,7 @@ int avrcp_set_volume(struct btd_device *dev, uint8_t volume)
> {
> struct avrcp_server *server;
> struct avrcp *session;
> - uint8_t buf[AVRCP_HEADER_LENGTH + 2];
> + uint8_t buf[AVRCP_HEADER_LENGTH + 1];
> struct avrcp_header *pdu = (void *) buf;
>
> server = find_server(servers, device_get_adapter(dev));
> --
> 1.8.3.2
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH] unit/avctp: Add TP/NFR/BV-04-C test
From: Andrei Emeltchenko @ 2014-02-04 13:47 UTC (permalink / raw)
To: linux-bluetooth
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Add test TP/NFR/BV-04-C for AVCTP.
---
unit/test-avctp.c | 40 +++++++++++++++++++++++++++++++---------
1 file changed, 31 insertions(+), 9 deletions(-)
diff --git a/unit/test-avctp.c b/unit/test-avctp.c
index 6d7e34a..581f88c 100644
--- a/unit/test-avctp.c
+++ b/unit/test-avctp.c
@@ -240,15 +240,6 @@ static void execute_context(struct context *context)
destroy_context(context);
}
-static void test_client(gconstpointer data)
-{
- struct context *context = create_context(0x0100, data);
-
- avctp_send_vendordep_req(context->session, 0, 0, NULL, 0, NULL, NULL);
-
- execute_context(context);
-}
-
static size_t handler(struct avctp *session,
uint8_t transaction, uint8_t *code,
uint8_t *subunit, uint8_t *operands,
@@ -265,6 +256,33 @@ static size_t handler(struct avctp *session,
return operand_count;
}
+static gboolean handler_response(struct avctp *session,
+ uint8_t code, uint8_t subunit,
+ uint8_t *operands, size_t operand_count,
+ void *user_data)
+{
+ struct context *context = user_data;
+
+ DBG("code 0x%02x subunit %d operand_count %zu", code, subunit,
+ operand_count);
+
+ g_assert_cmpint(code, ==, 0x0a);
+ g_assert_cmpint(subunit, ==, 0);
+ g_assert_cmpint(operand_count, ==, 0);
+
+ return context_quit(context);
+}
+
+static void test_client(gconstpointer data)
+{
+ struct context *context = create_context(0x0100, data);
+
+ avctp_send_vendordep_req(context->session, 0, 0, NULL, 0,
+ handler_response, context);
+
+ execute_context(context);
+}
+
static void test_server(gconstpointer data)
{
struct context *context = create_context(0x0100, data);
@@ -322,6 +340,10 @@ int main(int argc, char *argv[])
raw_pdu(0x00, 0x11, 0x0e, 0x00, 0x00, 0x00),
raw_pdu(0x02, 0x11, 0x0e, 0x00, 0x00, 0x00));
+ define_test("/TP/NFR/BV-04-C", test_client,
+ raw_pdu(0x00, 0x11, 0x0e, 0x00, 0x00, 0x00),
+ raw_pdu(0x02, 0x11, 0x0e, 0x0a, 0x00, 0x00));
+
define_test("/TP/NFR/BI-01-C", test_server,
raw_pdu(0x00, 0xff, 0xff, 0x00, 0x00, 0x00),
raw_pdu(0x03, 0xff, 0xff));
--
1.8.3.2
^ permalink raw reply related
* Re: [PATCH] android/avctp: Fix memory leak: unregister pdu handler
From: Luiz Augusto von Dentz @ 2014-02-04 13:47 UTC (permalink / raw)
To: Andrei Emeltchenko; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <1391506089-23985-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
Hi Andrei,
On Tue, Feb 4, 2014 at 11:28 AM, Andrei Emeltchenko
<Andrei.Emeltchenko.news@gmail.com> wrote:
> From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
>
> Unregister pdu handlers on shutdown.
> ---
> android/avctp.c | 9 +++++++++
> 1 file changed, 9 insertions(+)
>
> diff --git a/android/avctp.c b/android/avctp.c
> index 8f35403..8681cb0 100644
> --- a/android/avctp.c
> +++ b/android/avctp.c
> @@ -1462,6 +1462,15 @@ void avctp_shutdown(struct avctp *session)
> if (session->browsing)
> avctp_channel_destroy(session->browsing);
>
> + if (session->passthrough_id > 0)
> + avctp_unregister_pdu_handler(session, session->passthrough_id);
> +
> + if (session->unit_id > 0)
> + avctp_unregister_pdu_handler(session, session->unit_id);
> +
> + if (session->subunit_id > 0)
> + avctp_unregister_pdu_handler(session, session->subunit_id);
> +
> if (session->control)
> avctp_channel_destroy(session->control);
>
> --
> 1.8.3.2
There is no leak, avctp_channel_destroy cleanup all the registered handlers.
--
Luiz Augusto von Dentz
^ permalink raw reply
* Re: [PATCH] Bluetooth: hidp: make sure input buffers are big enough
From: Jiri Kosina @ 2014-02-04 13:46 UTC (permalink / raw)
To: David Herrmann
Cc: Marcel Holtmann, open list:HID CORE LAYER,
linux-bluetooth@vger.kernel.org development, Gustavo F. Padovan
In-Reply-To: <CANq1E4S++uqMzQue_0jC3N=Lm8Os5V-48Hw5M4vWvM+2Vx91yA@mail.gmail.com>
On Mon, 3 Feb 2014, David Herrmann wrote:
> >> >> Due to various reasons I will not have access to any testing HW for the
> >> >> upcoming 2-3 days, so if you can cook something up in that timeframe, it'd
> >> >> be appreciated.
> >> >>
> >> >> Otherwise I'll be working on it by the end of this week.
> >> >
> >> > David,
> >> >
> >> > just got back to this, finally ... did you have time to work on this at
> >> > all, or should I just start from scratch?
> >>
> >> Sorry, no. Fosdem is this weekend and I needed to get my code ready
> >> for that. But I'll finally have time again next week.
> >
> > Okay, thanks. I then guess we should proceed with this bandaid (double
> > allocation) for 3.14
>
> It would be really nice if we could get the HIDP patch into 3.14-rc2
> and backported to stable. There have been quite a bunch of reports now
> and I dislike adding a GFP_ATOMIC allocation in HID core.
I agree with David; Gustavo, what is your take on this, please?
Thanks,
--
Jiri Kosina
SUSE Labs
^ permalink raw reply
* Re: [PATCH] unit/avctp: Add connection establishment dummy tests
From: Luiz Augusto von Dentz @ 2014-02-04 13:46 UTC (permalink / raw)
To: Andrei Emeltchenko, linux-bluetooth@vger.kernel.org
In-Reply-To: <20140204115347.GL2930@aemeltch-MOBL1>
Hi Andrei,
On Tue, Feb 4, 2014 at 1:53 PM, Andrei Emeltchenko
<Andrei.Emeltchenko.news@gmail.com> wrote:
> On Mon, Feb 03, 2014 at 02:23:18PM +0200, Andrei Emeltchenko wrote:
>> From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
>
> ping
>
>>
>> Add some tests checking that L2CAP connection is established, so they
>> are basically dummy tests.
>> ---
>> unit/test-avctp.c | 30 +++++++++++++++++++++++++++---
>> 1 file changed, 27 insertions(+), 3 deletions(-)
>>
>> diff --git a/unit/test-avctp.c b/unit/test-avctp.c
>> index 041e0c0..c0d16a4 100644
>> --- a/unit/test-avctp.c
>> +++ b/unit/test-avctp.c
>> @@ -220,10 +220,8 @@ static struct context *create_context(uint16_t version, gconstpointer data)
>> return context;
>> }
>>
>> -static void execute_context(struct context *context)
>> +static void destroy_context(struct context *context)
>> {
>> - g_main_loop_run(context->main_loop);
>> -
>> if (context->source > 0)
>> g_source_remove(context->source);
>>
>> @@ -235,6 +233,13 @@ static void execute_context(struct context *context)
>> g_free(context);
>> }
>>
>> +static void execute_context(struct context *context)
>> +{
>> + g_main_loop_run(context->main_loop);
>> +
>> + destroy_context(context);
>> +}
>> +
>> static void test_client(gconstpointer data)
>> {
>> struct context *context = create_context(0x0100, data);
>> @@ -253,6 +258,13 @@ static void test_server(gconstpointer data)
>> execute_context(context);
>> }
>>
>> +static void test_dummy(gconstpointer data)
>> +{
>> + struct context *context = create_context(0x0100, data);
>> +
>> + destroy_context(context);
>> +}
>> +
>> int main(int argc, char *argv[])
>> {
>> g_test_init(&argc, &argv, NULL);
>> @@ -260,6 +272,18 @@ int main(int argc, char *argv[])
>> if (g_test_verbose())
>> __btd_log_init("*", 0);
>>
>> + /* Connection Channel Management tests */
>> +
>> + /*
>> + * Tests are checking that IUT is able to request establishing
>> + * channels, since we already have connection through socketpair
>> + * the tests are dummy.
>> + */
>> + define_test("/TP/CCM/BV-01-C", test_dummy, raw_pdu(0x00));
>> + define_test("/TP/CCM/BV-02-C", test_dummy, raw_pdu(0x00));
>> + define_test("/TP/CCM/BV-03-C", test_dummy, raw_pdu(0x00));
>> + define_test("/TP/CCM/BV-04-C", test_dummy, raw_pdu(0x00));
>> +
>> define_test("/TP/NFR/BV-01-C", test_client,
>> raw_pdu(0x00, 0x11, 0x0e, 0x00, 0x00, 0x00));
>>
>> --
>> 1.8.3.2
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
> --
Applied, thanks.
--
Luiz Augusto von Dentz
^ permalink raw reply
* Re: [PATCH] unit/avctp: Add test TP/NFR/BV-03-C
From: Luiz Augusto von Dentz @ 2014-02-04 13:45 UTC (permalink / raw)
To: Andrei Emeltchenko; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <1391514294-25337-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
Hi Andrei,
On Tue, Feb 4, 2014 at 1:44 PM, Andrei Emeltchenko
<Andrei.Emeltchenko.news@gmail.com> wrote:
> From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
>
> The test verifies that IUT (TG) correctly reports the parameters of the
> incoming command in the handler callback.
> ---
> unit/test-avctp.c | 31 +++++++++++++++++++++++++++++++
> 1 file changed, 31 insertions(+)
>
> diff --git a/unit/test-avctp.c b/unit/test-avctp.c
> index c0d16a4..6d7e34a 100644
> --- a/unit/test-avctp.c
> +++ b/unit/test-avctp.c
> @@ -249,10 +249,35 @@ static void test_client(gconstpointer data)
> execute_context(context);
> }
>
> +static size_t handler(struct avctp *session,
> + uint8_t transaction, uint8_t *code,
> + uint8_t *subunit, uint8_t *operands,
> + size_t operand_count, void *user_data)
> +{
> + DBG("transaction %d code %d subunit %d operand_count %zu",
> + transaction, *code, *subunit, operand_count);
> +
> + g_assert_cmpint(transaction, ==, 0);
> + g_assert_cmpint(*code, ==, 0);
> + g_assert_cmpint(*subunit, ==, 0);
> + g_assert_cmpint(operand_count, ==, 0);
> +
> + return operand_count;
> +}
> +
> static void test_server(gconstpointer data)
> {
> struct context *context = create_context(0x0100, data);
>
> + if (g_str_equal(context->data->test_name, "/TP/NFR/BV-03-C")) {
> + int ret;
> +
> + ret = avctp_register_pdu_handler(context->session, 0x00,
> + handler, NULL);
> + DBG("ret %d", ret);
> + g_assert_cmpint(ret, !=, 0);
> + }
> +
> g_idle_add(send_pdu, context);
>
> execute_context(context);
> @@ -284,6 +309,8 @@ int main(int argc, char *argv[])
> define_test("/TP/CCM/BV-03-C", test_dummy, raw_pdu(0x00));
> define_test("/TP/CCM/BV-04-C", test_dummy, raw_pdu(0x00));
>
> + /* Non-Fragmented Messages tests */
> +
> define_test("/TP/NFR/BV-01-C", test_client,
> raw_pdu(0x00, 0x11, 0x0e, 0x00, 0x00, 0x00));
>
> @@ -291,6 +318,10 @@ int main(int argc, char *argv[])
> raw_pdu(0x00, 0x11, 0x0e, 0x00, 0x00, 0x00),
> raw_pdu(0x02, 0x11, 0x0e, 0x0a, 0x00, 0x00));
>
> + define_test("/TP/NFR/BV-03-C", test_server,
> + raw_pdu(0x00, 0x11, 0x0e, 0x00, 0x00, 0x00),
> + raw_pdu(0x02, 0x11, 0x0e, 0x00, 0x00, 0x00));
> +
> define_test("/TP/NFR/BI-01-C", test_server,
> raw_pdu(0x00, 0xff, 0xff, 0x00, 0x00, 0x00),
> raw_pdu(0x03, 0xff, 0xff));
> --
> 1.8.3.2
>
> --
Applied, thanks.
--
Luiz Augusto von Dentz
^ permalink raw reply
* [PATCH v3] android/hal-audio: Add simple downmix to mono
From: Andrzej Kaczmarek @ 2014-02-04 13:38 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Andrzej Kaczmarek
This patch adds simple downmix support from stereo to mono in order to
support mono channel mode as it's mandatory for SBC codec. It uses
simple (L+R)/2 calculation which should be good enough.
---
android/hal-audio.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 49 insertions(+), 5 deletions(-)
diff --git a/android/hal-audio.c b/android/hal-audio.c
index efdf823..f90265b 100644
--- a/android/hal-audio.c
+++ b/android/hal-audio.c
@@ -36,9 +36,12 @@
#include "hal-log.h"
#include "hal-msg.h"
#include "../profiles/audio/a2dp-codecs.h"
+#include "../src/shared/util.h"
#define FIXED_A2DP_PLAYBACK_LATENCY_MS 25
+#define FIXED_BUFFER_SIZE (20 * 512)
+
#define MAX_FRAMES_IN_PAYLOAD 15
static const uint8_t a2dp_src_uuid[] = {
@@ -220,6 +223,8 @@ struct a2dp_stream_out {
struct audio_endpoint *ep;
enum a2dp_state_t audio_state;
struct audio_input_config cfg;
+
+ uint8_t *downmix_buf;
};
struct a2dp_audio_dev {
@@ -230,7 +235,8 @@ struct a2dp_audio_dev {
static const a2dp_sbc_t sbc_presets[] = {
{
.frequency = SBC_SAMPLING_FREQ_44100 | SBC_SAMPLING_FREQ_48000,
- .channel_mode = SBC_CHANNEL_MODE_DUAL_CHANNEL |
+ .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,
@@ -826,6 +832,21 @@ static void unregister_endpoints(void)
}
}
+static void downmix_to_mono(struct a2dp_stream_out *out, const uint8_t *buffer,
+ size_t bytes)
+{
+ const int16_t *input = (const void *) buffer;
+ int16_t *output = (void *) out->downmix_buf;
+ size_t i;
+
+ for (i = 0; i < bytes / 2; i++) {
+ int16_t l = le16_to_cpu(get_unaligned(&input[i * 2]));
+ int16_t r = le16_to_cpu(get_unaligned(&input[i * 2 + 1]));
+
+ put_unaligned(cpu_to_le16((l + r) / 2), &output[i]);
+ }
+}
+
static ssize_t out_write(struct audio_stream_out *stream, const void *buffer,
size_t bytes)
{
@@ -853,6 +874,18 @@ static ssize_t out_write(struct audio_stream_out *stream, const void *buffer,
return -1;
}
+ if (out->cfg.channels == AUDIO_CHANNEL_OUT_MONO) {
+ if (!out->downmix_buf) {
+ error("audio: downmix buffer not initialized");
+ return -1;
+ }
+
+ downmix_to_mono(out, buffer, bytes);
+
+ return out->ep->codec->write_data(out->ep->codec_data,
+ out->downmix_buf, bytes / 2, out->ep->fd) * 2;
+ }
+
return out->ep->codec->write_data(out->ep->codec_data, buffer,
bytes, out->ep->fd);
}
@@ -890,16 +923,18 @@ static size_t out_get_buffer_size(const struct audio_stream *stream)
* use magic value here and out_write code takes care of splitting
* input buffer into multiple media packets.
*/
- return 20 * 512;
+ return FIXED_BUFFER_SIZE;
}
static uint32_t out_get_channels(const struct audio_stream *stream)
{
- struct a2dp_stream_out *out = (struct a2dp_stream_out *) stream;
-
DBG("");
- return out->cfg.channels;
+ /* AudioFlinger can only provide stereo stream, so we return it here and
+ * later we'll downmix this to mono in case codec requires it
+ */
+
+ return AUDIO_CHANNEL_OUT_STEREO;
}
static audio_format_t out_get_format(const struct audio_stream *stream)
@@ -1212,6 +1247,12 @@ static int audio_open_output_stream(struct audio_hw_device *dev,
free(preset);
+ if (out->cfg.channels == AUDIO_CHANNEL_OUT_MONO) {
+ out->downmix_buf = malloc(FIXED_BUFFER_SIZE / 2);
+ if (!out->downmix_buf)
+ goto fail;
+ }
+
*stream_out = &out->stream;
a2dp_dev->out = out;
@@ -1230,6 +1271,7 @@ 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 a2dp_stream_out *out = (struct a2dp_stream_out *) stream;
struct audio_endpoint *ep = a2dp_dev->out->ep;
DBG("");
@@ -1243,6 +1285,8 @@ static void audio_close_output_stream(struct audio_hw_device *dev,
ep->codec->cleanup(ep->codec_data);
ep->codec_data = NULL;
+ free(out->downmix_buf);
+
free(stream);
a2dp_dev->out = NULL;
}
--
1.8.5.3
^ permalink raw reply related
* [PATCH v2] android/hal-audio: Add simple downmix to mono
From: Andrzej Kaczmarek @ 2014-02-04 13:16 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Andrzej Kaczmarek
This patch adds simple downmix support from stereo to mono in order to
support mono channel mode as it's mandatory for SBC codec. It uses
simple (L+R)/2 calculation which should be good enough.
---
android/hal-audio.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 49 insertions(+), 5 deletions(-)
diff --git a/android/hal-audio.c b/android/hal-audio.c
index efdf823..cef70aa 100644
--- a/android/hal-audio.c
+++ b/android/hal-audio.c
@@ -36,9 +36,12 @@
#include "hal-log.h"
#include "hal-msg.h"
#include "../profiles/audio/a2dp-codecs.h"
+#include "../src/shared/util.h"
#define FIXED_A2DP_PLAYBACK_LATENCY_MS 25
+#define FIXED_BUFFER_SIZE (20 * 512)
+
#define MAX_FRAMES_IN_PAYLOAD 15
static const uint8_t a2dp_src_uuid[] = {
@@ -220,6 +223,8 @@ struct a2dp_stream_out {
struct audio_endpoint *ep;
enum a2dp_state_t audio_state;
struct audio_input_config cfg;
+
+ uint8_t *downmix_buf;
};
struct a2dp_audio_dev {
@@ -230,7 +235,8 @@ struct a2dp_audio_dev {
static const a2dp_sbc_t sbc_presets[] = {
{
.frequency = SBC_SAMPLING_FREQ_44100 | SBC_SAMPLING_FREQ_48000,
- .channel_mode = SBC_CHANNEL_MODE_DUAL_CHANNEL |
+ .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,
@@ -826,6 +832,21 @@ static void unregister_endpoints(void)
}
}
+static void downmix_to_mono(struct a2dp_stream_out *out, const uint8_t *buffer,
+ size_t bytes)
+{
+ size_t i;
+ int16_t *input = (int16_t *) buffer;
+ int16_t *output = (int16_t *) out->downmix_buf;
+
+ for (i = 0; i < bytes / 2; i++) {
+ int16_t l = le16_to_cpu(get_unaligned(&input[i * 2]));
+ int16_t r = le16_to_cpu(get_unaligned(&input[i * 2 + 1]));
+
+ output[i] = (l + r) / 2;
+ }
+}
+
static ssize_t out_write(struct audio_stream_out *stream, const void *buffer,
size_t bytes)
{
@@ -853,6 +874,18 @@ static ssize_t out_write(struct audio_stream_out *stream, const void *buffer,
return -1;
}
+ if (out->cfg.channels == AUDIO_CHANNEL_OUT_MONO) {
+ if (!out->downmix_buf) {
+ error("audio: downmix buffer not initialized");
+ return -1;
+ }
+
+ downmix_to_mono(out, buffer, bytes);
+
+ return out->ep->codec->write_data(out->ep->codec_data,
+ out->downmix_buf, bytes / 2, out->ep->fd) * 2;
+ }
+
return out->ep->codec->write_data(out->ep->codec_data, buffer,
bytes, out->ep->fd);
}
@@ -890,16 +923,18 @@ static size_t out_get_buffer_size(const struct audio_stream *stream)
* use magic value here and out_write code takes care of splitting
* input buffer into multiple media packets.
*/
- return 20 * 512;
+ return FIXED_BUFFER_SIZE;
}
static uint32_t out_get_channels(const struct audio_stream *stream)
{
- struct a2dp_stream_out *out = (struct a2dp_stream_out *) stream;
-
DBG("");
- return out->cfg.channels;
+ /* AudioFlinger can only provide stereo stream, so we return it here and
+ * later we'll downmix this to mono in case codec requires it
+ */
+
+ return AUDIO_CHANNEL_OUT_STEREO;
}
static audio_format_t out_get_format(const struct audio_stream *stream)
@@ -1212,6 +1247,12 @@ static int audio_open_output_stream(struct audio_hw_device *dev,
free(preset);
+ if (out->cfg.channels == AUDIO_CHANNEL_OUT_MONO) {
+ out->downmix_buf = malloc(FIXED_BUFFER_SIZE / 2);
+ if (!out->downmix_buf)
+ goto fail;
+ }
+
*stream_out = &out->stream;
a2dp_dev->out = out;
@@ -1230,6 +1271,7 @@ 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 a2dp_stream_out *out = (struct a2dp_stream_out *) stream;
struct audio_endpoint *ep = a2dp_dev->out->ep;
DBG("");
@@ -1243,6 +1285,8 @@ static void audio_close_output_stream(struct audio_hw_device *dev,
ep->codec->cleanup(ep->codec_data);
ep->codec_data = NULL;
+ free(out->downmix_buf);
+
free(stream);
a2dp_dev->out = NULL;
}
--
1.8.5.3
^ permalink raw reply related
* Re: [PATCH 1/3] avrcp: Avoid unneeded calculation
From: Andrei Emeltchenko @ 2014-02-04 13:05 UTC (permalink / raw)
To: Luiz Augusto von Dentz; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <CABBYNZKTZ4WMTp26ajSOxqkNDj4D9--L2=V6YvG6QzuyqrufZQ@mail.gmail.com>
Hi Luiz,
On Tue, Feb 04, 2014 at 02:49:02PM +0200, Luiz Augusto von Dentz wrote:
> Hi Andrei,
>
> On Tue, Feb 4, 2014 at 1:55 PM, Andrei Emeltchenko
> <Andrei.Emeltchenko.news@gmail.com> wrote:
> > On Thu, Jan 30, 2014 at 06:12:54PM +0200, Andrei Emeltchenko wrote:
> >> From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
> >>
> >> There no need to calculate those values
> >
> > ping
> >
> >> ---
> >> profiles/audio/avrcp.c | 4 ++--
> >> 1 file changed, 2 insertions(+), 2 deletions(-)
> >>
> >> diff --git a/profiles/audio/avrcp.c b/profiles/audio/avrcp.c
> >> index fa5adab..2e1a940 100644
> >> --- a/profiles/audio/avrcp.c
> >> +++ b/profiles/audio/avrcp.c
> >> @@ -3177,7 +3177,7 @@ static void avrcp_register_notification(struct avrcp *session, uint8_t event)
> >> pdu->params[0] = event;
> >> pdu->params_len = htons(AVRCP_REGISTER_NOTIFICATION_PARAM_LENGTH);
> >>
> >> - length = AVRCP_HEADER_LENGTH + ntohs(pdu->params_len);
> >> + length = AVRCP_HEADER_LENGTH + AVRCP_REGISTER_NOTIFICATION_PARAM_LENGTH;
> >>
> >> avctp_send_vendordep_req(session->conn, AVC_CTYPE_NOTIFY,
> >> AVC_SUBUNIT_PANEL, buf, length,
> >> @@ -3250,7 +3250,7 @@ static void avrcp_get_capabilities(struct avrcp *session)
> >> pdu->params[0] = CAP_EVENTS_SUPPORTED;
> >> pdu->params_len = htons(AVRCP_GET_CAPABILITIES_PARAM_LENGTH);
> >>
> >> - length = AVRCP_HEADER_LENGTH + ntohs(pdu->params_len);
> >> + length = AVRCP_HEADER_LENGTH + AVRCP_GET_CAPABILITIES_PARAM_LENGTH;
> >>
> >> avctp_send_vendordep_req(session->conn, AVC_CTYPE_STATUS,
> >> AVC_SUBUNIT_PANEL, buf, length,
> >> --
> >> 1.8.3.2
>
> I will leave this as it for now, we will probably create a avrcp_send
> helper to have this in common place.
OK, though those
a = ntohs(b);
c = htons(a);
looks IMO really ugly
Best regards
Andrei Emeltchenko
^ permalink raw reply
* Re: [PATCHv2] android/avrcp: Decouple AVRCP logic from btio
From: Andrei Emeltchenko @ 2014-02-04 13:03 UTC (permalink / raw)
To: Luiz Augusto von Dentz; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <CABBYNZKLwPzEsLCLDGr6cMgYQRobcfQ7W_EqqUpSSvBp4=hGVg@mail.gmail.com>
Hi Luiz,
On Tue, Feb 04, 2014 at 02:50:11PM +0200, Luiz Augusto von Dentz wrote:
> Hi Andrei,
>
> On Tue, Feb 4, 2014 at 1:56 PM, Andrei Emeltchenko
> <Andrei.Emeltchenko.news@gmail.com> wrote:
> > On Mon, Feb 03, 2014 at 11:16:17AM +0200, Andrei Emeltchenko wrote:
> >> From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
> >>
> >> The patch makes AVRCP to be channel-agnostic so that it might be used in
> >> unit tests. The idea is that all AVRCP logic would come to avrcp-lib and
> >> channel stuff got to avrcp.
>
> I think we discussed this offline and decided not to have a separate
> file for now.
So is the idea is to have unit-avrcp to be compiled with btio, etc?
I will then just to link everything what android/avrcp needs.
Best regards
Andrei Emeltchenko
^ permalink raw reply
* Re: [PATCHv2] android/avrcp: Decouple AVRCP logic from btio
From: Luiz Augusto von Dentz @ 2014-02-04 12:50 UTC (permalink / raw)
To: Andrei Emeltchenko, linux-bluetooth@vger.kernel.org
In-Reply-To: <20140204115622.GN2930@aemeltch-MOBL1>
Hi Andrei,
On Tue, Feb 4, 2014 at 1:56 PM, Andrei Emeltchenko
<Andrei.Emeltchenko.news@gmail.com> wrote:
> On Mon, Feb 03, 2014 at 11:16:17AM +0200, Andrei Emeltchenko wrote:
>> From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
>>
>> The patch makes AVRCP to be channel-agnostic so that it might be used in
>> unit tests. The idea is that all AVRCP logic would come to avrcp-lib and
>> channel stuff got to avrcp.
>
> ping
>
>> ---
>> android/Android.mk | 1 +
>> android/Makefile.am | 1 +
>> android/avrcp-lib.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++++
>> android/avrcp-lib.h | 32 ++++++++++++++++++++
>> android/avrcp.c | 44 ++-------------------------
>> 5 files changed, 122 insertions(+), 41 deletions(-)
>> create mode 100644 android/avrcp-lib.c
>> create mode 100644 android/avrcp-lib.h
>>
>> diff --git a/android/Android.mk b/android/Android.mk
>> index 09ed32d..2772b58 100644
>> --- a/android/Android.mk
>> +++ b/android/Android.mk
>> @@ -30,6 +30,7 @@ LOCAL_SRC_FILES := \
>> bluez/android/avdtp.c \
>> bluez/android/a2dp.c \
>> bluez/android/avctp.c \
>> + bluez/android/avrcp-lib.c \
>> bluez/android/avrcp.c \
>> bluez/android/pan.c \
>> bluez/src/log.c \
>> diff --git a/android/Makefile.am b/android/Makefile.am
>> index e065c0c..29cbf79 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-lib.h android/avrcp-lib.c \
>> android/avrcp.h android/avrcp.c \
>> android/socket.h android/socket.c \
>> android/pan.h android/pan.c \
>> diff --git a/android/avrcp-lib.c b/android/avrcp-lib.c
>> new file mode 100644
>> index 0000000..a4bfe6d
>> --- /dev/null
>> +++ b/android/avrcp-lib.c
>> @@ -0,0 +1,85 @@
>> +/*
>> + *
>> + * 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
>> + * (at your option) any later version.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
>> + * GNU General Public License for more details.
>> + *
>> + * You should have received a copy of the GNU General Public License
>> + * along with this program; if not, write to the Free Software
>> + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
>> + *
>> + */
>> +
>> +#ifdef HAVE_CONFIG_H
>> +#include <config.h>
>> +#endif
>> +
>> +#include <stdbool.h>
>> +#include <glib.h>
>> +
>> +#include "lib/bluetooth.h"
>> +
>> +#include "src/log.h"
>> +
>> +#include "avctp.h"
>> +#include "avrcp-lib.h"
>> +
>> +static GSList *devices = NULL;
>> +
>> +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);
>> +}
>> +
>> +void avrcp_free_all(void)
>> +{
>> + g_slist_free_full(devices, avrcp_device_free);
>> + devices = NULL;
>> +}
>> +
>> +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);
>> +}
>> +
>> +struct avrcp_device *avrcp_find(bdaddr_t *dst)
>> +{
>> + GSList *l;
>> +
>> + l = g_slist_find_custom(devices, dst, device_cmp);
>> + if (!l)
>> + return NULL;
>> +
>> + return l->data;
>> +}
>> diff --git a/android/avrcp-lib.h b/android/avrcp-lib.h
>> new file mode 100644
>> index 0000000..a7213fb
>> --- /dev/null
>> +++ b/android/avrcp-lib.h
>> @@ -0,0 +1,32 @@
>> +/*
>> + *
>> + * 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
>> + * (at your option) any later version.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
>> + * GNU General Public License for more details.
>> + *
>> + * You should have received a copy of the GNU General Public License
>> + * along with this program; if not, write to the Free Software
>> + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
>> + *
>> + */
>> +
>> +struct avrcp_device {
>> + bdaddr_t dst;
>> + struct avctp *session;
>> +};
>> +
>> +struct avrcp_device *avrcp_device_new(const bdaddr_t *dst);
>> +void avrcp_device_free(void *data);
>> +void avrcp_free_all(void);
>> +struct avrcp_device *avrcp_find(bdaddr_t *dst);
>> diff --git a/android/avrcp.c b/android/avrcp.c
>> index ef833df..ff923cb 100644
>> --- a/android/avrcp.c
>> +++ b/android/avrcp.c
>> @@ -38,6 +38,7 @@
>> #include "hal-msg.h"
>> #include "ipc.h"
>> #include "avctp.h"
>> +#include "avrcp-lib.h"
>>
>> #define L2CAP_PSM_AVCTP 0x17
>>
>> @@ -48,14 +49,8 @@
>>
>> 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[] = {
>> };
>>
>> @@ -127,36 +122,6 @@ 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;
>> @@ -175,7 +140,6 @@ static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
>> char address[18];
>> uint16_t imtu, omtu;
>> GError *gerr = NULL;
>> - GSList *l;
>> int fd;
>>
>> if (err) {
>> @@ -199,8 +163,7 @@ static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
>> ba2str(&dst, address);
>> DBG("Incoming connection from %s", address);
>>
>> - l = g_slist_find_custom(devices, &dst, device_cmp);
>> - if (l) {
>> + if (avrcp_find(&dst)) {
>> error("Unexpected connection");
>> return;
>> }
>> @@ -274,8 +237,7 @@ void bt_avrcp_unregister(void)
>> {
>> DBG("");
>>
>> - g_slist_free_full(devices, avrcp_device_free);
>> - devices = NULL;
>> + avrcp_free_all();
>>
>> ipc_unregister(HAL_SERVICE_ID_AVRCP);
>>
>> --
>> 1.8.3.2
I think we discussed this offline and decided not to have a separate
file for now.
--
Luiz Augusto von Dentz
^ permalink raw reply
* Re: [PATCH 1/3] avrcp: Avoid unneeded calculation
From: Luiz Augusto von Dentz @ 2014-02-04 12:49 UTC (permalink / raw)
To: Andrei Emeltchenko, linux-bluetooth@vger.kernel.org
In-Reply-To: <20140204115549.GM2930@aemeltch-MOBL1>
Hi Andrei,
On Tue, Feb 4, 2014 at 1:55 PM, Andrei Emeltchenko
<Andrei.Emeltchenko.news@gmail.com> wrote:
> On Thu, Jan 30, 2014 at 06:12:54PM +0200, Andrei Emeltchenko wrote:
>> From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
>>
>> There no need to calculate those values
>
> ping
>
>> ---
>> profiles/audio/avrcp.c | 4 ++--
>> 1 file changed, 2 insertions(+), 2 deletions(-)
>>
>> diff --git a/profiles/audio/avrcp.c b/profiles/audio/avrcp.c
>> index fa5adab..2e1a940 100644
>> --- a/profiles/audio/avrcp.c
>> +++ b/profiles/audio/avrcp.c
>> @@ -3177,7 +3177,7 @@ static void avrcp_register_notification(struct avrcp *session, uint8_t event)
>> pdu->params[0] = event;
>> pdu->params_len = htons(AVRCP_REGISTER_NOTIFICATION_PARAM_LENGTH);
>>
>> - length = AVRCP_HEADER_LENGTH + ntohs(pdu->params_len);
>> + length = AVRCP_HEADER_LENGTH + AVRCP_REGISTER_NOTIFICATION_PARAM_LENGTH;
>>
>> avctp_send_vendordep_req(session->conn, AVC_CTYPE_NOTIFY,
>> AVC_SUBUNIT_PANEL, buf, length,
>> @@ -3250,7 +3250,7 @@ static void avrcp_get_capabilities(struct avrcp *session)
>> pdu->params[0] = CAP_EVENTS_SUPPORTED;
>> pdu->params_len = htons(AVRCP_GET_CAPABILITIES_PARAM_LENGTH);
>>
>> - length = AVRCP_HEADER_LENGTH + ntohs(pdu->params_len);
>> + length = AVRCP_HEADER_LENGTH + AVRCP_GET_CAPABILITIES_PARAM_LENGTH;
>>
>> avctp_send_vendordep_req(session->conn, AVC_CTYPE_STATUS,
>> AVC_SUBUNIT_PANEL, buf, length,
>> --
>> 1.8.3.2
I will leave this as it for now, we will probably create a avrcp_send
helper to have this in common place.
--
Luiz Augusto von Dentz
^ permalink raw reply
* Re: [PATCH] android/hal-audio: Add simple downmix to mono
From: Luiz Augusto von Dentz @ 2014-02-04 12:44 UTC (permalink / raw)
To: Szymon Janc; +Cc: Andrzej Kaczmarek, linux-bluetooth@vger.kernel.org
In-Reply-To: <9469082.LestBIZf2H@uw000953>
Hi Andrzej,
On Tue, Feb 4, 2014 at 1:49 PM, Szymon Janc <szymon.janc@tieto.com> wrote:
> Hi Andrzej,
>
> On Tuesday 04 of February 2014 12:37:22 Andrzej Kaczmarek wrote:
>> This patch adds simple downmix support from stereo to mono in order to
>> support mono channel mode as it's mandatory for SBC codec. It uses
>> simple (L+R)/2 calculation which should be good enough.
Not following this one, doesn't AudioFlinger supports mono?
^ permalink raw reply
* Re: [PATCHv2] android/avrcp: Decouple AVRCP logic from btio
From: Andrei Emeltchenko @ 2014-02-04 11:56 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1391418977-24811-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
On Mon, Feb 03, 2014 at 11:16:17AM +0200, Andrei Emeltchenko wrote:
> From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
>
> The patch makes AVRCP to be channel-agnostic so that it might be used in
> unit tests. The idea is that all AVRCP logic would come to avrcp-lib and
> channel stuff got to avrcp.
ping
> ---
> android/Android.mk | 1 +
> android/Makefile.am | 1 +
> android/avrcp-lib.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++++
> android/avrcp-lib.h | 32 ++++++++++++++++++++
> android/avrcp.c | 44 ++-------------------------
> 5 files changed, 122 insertions(+), 41 deletions(-)
> create mode 100644 android/avrcp-lib.c
> create mode 100644 android/avrcp-lib.h
>
> diff --git a/android/Android.mk b/android/Android.mk
> index 09ed32d..2772b58 100644
> --- a/android/Android.mk
> +++ b/android/Android.mk
> @@ -30,6 +30,7 @@ LOCAL_SRC_FILES := \
> bluez/android/avdtp.c \
> bluez/android/a2dp.c \
> bluez/android/avctp.c \
> + bluez/android/avrcp-lib.c \
> bluez/android/avrcp.c \
> bluez/android/pan.c \
> bluez/src/log.c \
> diff --git a/android/Makefile.am b/android/Makefile.am
> index e065c0c..29cbf79 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-lib.h android/avrcp-lib.c \
> android/avrcp.h android/avrcp.c \
> android/socket.h android/socket.c \
> android/pan.h android/pan.c \
> diff --git a/android/avrcp-lib.c b/android/avrcp-lib.c
> new file mode 100644
> index 0000000..a4bfe6d
> --- /dev/null
> +++ b/android/avrcp-lib.c
> @@ -0,0 +1,85 @@
> +/*
> + *
> + * 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
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
> + *
> + */
> +
> +#ifdef HAVE_CONFIG_H
> +#include <config.h>
> +#endif
> +
> +#include <stdbool.h>
> +#include <glib.h>
> +
> +#include "lib/bluetooth.h"
> +
> +#include "src/log.h"
> +
> +#include "avctp.h"
> +#include "avrcp-lib.h"
> +
> +static GSList *devices = NULL;
> +
> +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);
> +}
> +
> +void avrcp_free_all(void)
> +{
> + g_slist_free_full(devices, avrcp_device_free);
> + devices = NULL;
> +}
> +
> +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);
> +}
> +
> +struct avrcp_device *avrcp_find(bdaddr_t *dst)
> +{
> + GSList *l;
> +
> + l = g_slist_find_custom(devices, dst, device_cmp);
> + if (!l)
> + return NULL;
> +
> + return l->data;
> +}
> diff --git a/android/avrcp-lib.h b/android/avrcp-lib.h
> new file mode 100644
> index 0000000..a7213fb
> --- /dev/null
> +++ b/android/avrcp-lib.h
> @@ -0,0 +1,32 @@
> +/*
> + *
> + * 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
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
> + *
> + */
> +
> +struct avrcp_device {
> + bdaddr_t dst;
> + struct avctp *session;
> +};
> +
> +struct avrcp_device *avrcp_device_new(const bdaddr_t *dst);
> +void avrcp_device_free(void *data);
> +void avrcp_free_all(void);
> +struct avrcp_device *avrcp_find(bdaddr_t *dst);
> diff --git a/android/avrcp.c b/android/avrcp.c
> index ef833df..ff923cb 100644
> --- a/android/avrcp.c
> +++ b/android/avrcp.c
> @@ -38,6 +38,7 @@
> #include "hal-msg.h"
> #include "ipc.h"
> #include "avctp.h"
> +#include "avrcp-lib.h"
>
> #define L2CAP_PSM_AVCTP 0x17
>
> @@ -48,14 +49,8 @@
>
> 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[] = {
> };
>
> @@ -127,36 +122,6 @@ 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;
> @@ -175,7 +140,6 @@ static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
> char address[18];
> uint16_t imtu, omtu;
> GError *gerr = NULL;
> - GSList *l;
> int fd;
>
> if (err) {
> @@ -199,8 +163,7 @@ static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
> ba2str(&dst, address);
> DBG("Incoming connection from %s", address);
>
> - l = g_slist_find_custom(devices, &dst, device_cmp);
> - if (l) {
> + if (avrcp_find(&dst)) {
> error("Unexpected connection");
> return;
> }
> @@ -274,8 +237,7 @@ void bt_avrcp_unregister(void)
> {
> DBG("");
>
> - g_slist_free_full(devices, avrcp_device_free);
> - devices = NULL;
> + avrcp_free_all();
>
> ipc_unregister(HAL_SERVICE_ID_AVRCP);
>
> --
> 1.8.3.2
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH 1/3] avrcp: Avoid unneeded calculation
From: Andrei Emeltchenko @ 2014-02-04 11:55 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1391098376-26834-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
On Thu, Jan 30, 2014 at 06:12:54PM +0200, Andrei Emeltchenko wrote:
> From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
>
> There no need to calculate those values
ping
> ---
> profiles/audio/avrcp.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/profiles/audio/avrcp.c b/profiles/audio/avrcp.c
> index fa5adab..2e1a940 100644
> --- a/profiles/audio/avrcp.c
> +++ b/profiles/audio/avrcp.c
> @@ -3177,7 +3177,7 @@ static void avrcp_register_notification(struct avrcp *session, uint8_t event)
> pdu->params[0] = event;
> pdu->params_len = htons(AVRCP_REGISTER_NOTIFICATION_PARAM_LENGTH);
>
> - length = AVRCP_HEADER_LENGTH + ntohs(pdu->params_len);
> + length = AVRCP_HEADER_LENGTH + AVRCP_REGISTER_NOTIFICATION_PARAM_LENGTH;
>
> avctp_send_vendordep_req(session->conn, AVC_CTYPE_NOTIFY,
> AVC_SUBUNIT_PANEL, buf, length,
> @@ -3250,7 +3250,7 @@ static void avrcp_get_capabilities(struct avrcp *session)
> pdu->params[0] = CAP_EVENTS_SUPPORTED;
> pdu->params_len = htons(AVRCP_GET_CAPABILITIES_PARAM_LENGTH);
>
> - length = AVRCP_HEADER_LENGTH + ntohs(pdu->params_len);
> + length = AVRCP_HEADER_LENGTH + AVRCP_GET_CAPABILITIES_PARAM_LENGTH;
>
> avctp_send_vendordep_req(session->conn, AVC_CTYPE_STATUS,
> AVC_SUBUNIT_PANEL, buf, length,
> --
> 1.8.3.2
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH] unit/avctp: Add connection establishment dummy tests
From: Andrei Emeltchenko @ 2014-02-04 11:53 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1391430198-26823-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
On Mon, Feb 03, 2014 at 02:23:18PM +0200, Andrei Emeltchenko wrote:
> From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
ping
>
> Add some tests checking that L2CAP connection is established, so they
> are basically dummy tests.
> ---
> unit/test-avctp.c | 30 +++++++++++++++++++++++++++---
> 1 file changed, 27 insertions(+), 3 deletions(-)
>
> diff --git a/unit/test-avctp.c b/unit/test-avctp.c
> index 041e0c0..c0d16a4 100644
> --- a/unit/test-avctp.c
> +++ b/unit/test-avctp.c
> @@ -220,10 +220,8 @@ static struct context *create_context(uint16_t version, gconstpointer data)
> return context;
> }
>
> -static void execute_context(struct context *context)
> +static void destroy_context(struct context *context)
> {
> - g_main_loop_run(context->main_loop);
> -
> if (context->source > 0)
> g_source_remove(context->source);
>
> @@ -235,6 +233,13 @@ static void execute_context(struct context *context)
> g_free(context);
> }
>
> +static void execute_context(struct context *context)
> +{
> + g_main_loop_run(context->main_loop);
> +
> + destroy_context(context);
> +}
> +
> static void test_client(gconstpointer data)
> {
> struct context *context = create_context(0x0100, data);
> @@ -253,6 +258,13 @@ static void test_server(gconstpointer data)
> execute_context(context);
> }
>
> +static void test_dummy(gconstpointer data)
> +{
> + struct context *context = create_context(0x0100, data);
> +
> + destroy_context(context);
> +}
> +
> int main(int argc, char *argv[])
> {
> g_test_init(&argc, &argv, NULL);
> @@ -260,6 +272,18 @@ int main(int argc, char *argv[])
> if (g_test_verbose())
> __btd_log_init("*", 0);
>
> + /* Connection Channel Management tests */
> +
> + /*
> + * Tests are checking that IUT is able to request establishing
> + * channels, since we already have connection through socketpair
> + * the tests are dummy.
> + */
> + define_test("/TP/CCM/BV-01-C", test_dummy, raw_pdu(0x00));
> + define_test("/TP/CCM/BV-02-C", test_dummy, raw_pdu(0x00));
> + define_test("/TP/CCM/BV-03-C", test_dummy, raw_pdu(0x00));
> + define_test("/TP/CCM/BV-04-C", test_dummy, raw_pdu(0x00));
> +
> define_test("/TP/NFR/BV-01-C", test_client,
> raw_pdu(0x00, 0x11, 0x0e, 0x00, 0x00, 0x00));
>
> --
> 1.8.3.2
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH] android/hal-audio: Add simple downmix to mono
From: Szymon Janc @ 2014-02-04 11:49 UTC (permalink / raw)
To: Andrzej Kaczmarek; +Cc: linux-bluetooth
In-Reply-To: <1391513842-9548-1-git-send-email-andrzej.kaczmarek@tieto.com>
Hi Andrzej,
On Tuesday 04 of February 2014 12:37:22 Andrzej Kaczmarek wrote:
> This patch adds simple downmix support from stereo to mono in order to
> support mono channel mode as it's mandatory for SBC codec. It uses
> simple (L+R)/2 calculation which should be good enough.
> ---
> android/hal-audio.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++-----
> 1 file changed, 46 insertions(+), 5 deletions(-)
>
> diff --git a/android/hal-audio.c b/android/hal-audio.c
> index efdf823..b5b75d3 100644
> --- a/android/hal-audio.c
> +++ b/android/hal-audio.c
> @@ -39,6 +39,8 @@
>
> #define FIXED_A2DP_PLAYBACK_LATENCY_MS 25
>
> +#define FIXED_BUFFER_SIZE (20 * 512)
> +
> #define MAX_FRAMES_IN_PAYLOAD 15
>
> static const uint8_t a2dp_src_uuid[] = {
> @@ -220,6 +222,8 @@ struct a2dp_stream_out {
> struct audio_endpoint *ep;
> enum a2dp_state_t audio_state;
> struct audio_input_config cfg;
> +
> + uint8_t *downmix_buf;
> };
>
> struct a2dp_audio_dev {
> @@ -230,7 +234,8 @@ struct a2dp_audio_dev {
> static const a2dp_sbc_t sbc_presets[] = {
> {
> .frequency = SBC_SAMPLING_FREQ_44100 | SBC_SAMPLING_FREQ_48000,
> - .channel_mode = SBC_CHANNEL_MODE_DUAL_CHANNEL |
> + .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,
> @@ -826,6 +831,19 @@ static void unregister_endpoints(void)
> }
> }
>
> +static void prepare_downmix_buf(struct a2dp_stream_out *out,
> + const uint8_t *buffer, size_t bytes)
I'd name it something like downmix_to_mono() or mono_downmix().
> +{
> + size_t i;
> + int16_t *input = (int16_t *) buffer;
> + int16_t *output = (int16_t *) out->downmix_buf;
This might cause unaligned memory access.
> +
> + for (i = 0; i < bytes / 2; i++) {
> + int sum = ((int) input[i * 2] + input[i * 2 + 1]);
> + output[i] = sum >> 1;
I'd just divide by 2 here.
> + }
> +}
> +
> static ssize_t out_write(struct audio_stream_out *stream, const void *buffer,
> size_t bytes)
> {
> @@ -853,6 +871,18 @@ static ssize_t out_write(struct audio_stream_out *stream, const void *buffer,
> return -1;
> }
>
> + if (out->cfg.channels == AUDIO_CHANNEL_OUT_MONO) {
> + if (!out->downmix_buf) {
> + error("audio: downmix buffer not initialized");
> + return -1;
> + }
> +
> + prepare_downmix_buf(out, buffer, bytes);
> +
> + return out->ep->codec->write_data(out->ep->codec_data,
> + out->downmix_buf, bytes / 2, out->ep->fd) * 2;
> + }
> +
> return out->ep->codec->write_data(out->ep->codec_data, buffer,
> bytes, out->ep->fd);
> }
> @@ -890,16 +920,18 @@ static size_t out_get_buffer_size(const struct audio_stream *stream)
> * use magic value here and out_write code takes care of splitting
> * input buffer into multiple media packets.
> */
> - return 20 * 512;
> + return FIXED_BUFFER_SIZE;
> }
>
> static uint32_t out_get_channels(const struct audio_stream *stream)
> {
> - struct a2dp_stream_out *out = (struct a2dp_stream_out *) stream;
> -
> DBG("");
>
> - return out->cfg.channels;
> + /* AudioFlinger can only provide stereo stream, so we return it here and
> + * later we'll downmix this to mono in case codec requires it
> + */
> +
> + return AUDIO_CHANNEL_OUT_STEREO;
> }
>
> static audio_format_t out_get_format(const struct audio_stream *stream)
> @@ -1212,6 +1244,12 @@ static int audio_open_output_stream(struct audio_hw_device *dev,
>
> free(preset);
>
> + if (out->cfg.channels == AUDIO_CHANNEL_OUT_MONO) {
> + out->downmix_buf = malloc(FIXED_BUFFER_SIZE / 2);
> + if (!out->downmix_buf)
> + goto fail;
> + }
> +
> *stream_out = &out->stream;
> a2dp_dev->out = out;
>
> @@ -1230,6 +1268,7 @@ 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 a2dp_stream_out *out = (struct a2dp_stream_out *) stream;
> struct audio_endpoint *ep = a2dp_dev->out->ep;
>
> DBG("");
> @@ -1243,6 +1282,8 @@ static void audio_close_output_stream(struct audio_hw_device *dev,
> ep->codec->cleanup(ep->codec_data);
> ep->codec_data = NULL;
>
> + free(out->downmix_buf);
> +
> free(stream);
> a2dp_dev->out = NULL;
> }
>
--
Best regards,
Szymon Janc
^ 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