* Re: [PATCH 7/7] Add /hfp/test_hfp_gw_register_3 and /hfp/test_hfp_gw_register_4
From: Marcel Holtmann @ 2014-03-04 8:51 UTC (permalink / raw)
To: Marcin Kraglak; +Cc: linux-bluetooth@vger.kernel.org development
In-Reply-To: <CABD6X-+-pUjd36JQ_wb+LKQWimB4_TwL+aqk7koZkiLz_k5FaA@mail.gmail.com>
Hi Marcin,
>>> unit/test-hfp.c | 31 +++++++++++++++++++++++++++++++
>>> 1 file changed, 31 insertions(+)
>>>
>>> diff --git a/unit/test-hfp.c b/unit/test-hfp.c
>>> index 5e4fc11..64ecc60 100644
>>> --- a/unit/test-hfp.c
>>> +++ b/unit/test-hfp.c
>>> @@ -266,6 +266,33 @@ static const struct test_data test_register_2 = {
>>> .prefix = prefix_brsf
>>> };
>>>
>>> +static const char atbrsf_read[] = {'A', 'T', '+', 'B', 'R', 'S', 'F', '?',
>>> + '\r'};
>>> +
>>
>> = "AT+BRSF?\r";
>>
>>> +static const struct test_data test_register_3 = {
>>> + .command_cb = cmd_handler,
>>> + .server_send = atbrsf_read,
>>> + .data_len = sizeof(atbrsf_read),
>>> + .expected_rsp = err_rsp,
>>> + .expected_rsp_len = sizeof(err_rsp),
>>> + .result_cb = prefix_handler,
>>> + .expected_cmd_type = HFP_GW_CMD_TYPE_READ,
>>> + .prefix = prefix_brsf
>>> +};
>>> +
>>> +static const char prefix_d[] = "D";
>>
>> I wonder why here it is acceptable and above you are making the huge effort to give every character separately.
>
> I thought it will be more readable if raw data passed to socket will
> be declared as array, not string. Prefixes are passed as strings,
> because they are used in hfp_gw_register() Anyway Luiz suggested to
> use common framework for this test like raw_pdu(args...) ,
> define_test(name, function, args...), (it is used in test-avctp and
> test-avrcp). Will it look better for you?
besides the ending \0, what is actually the difference? It is just wasted effort to put in strings in array from. Just call strlen() instead of sizeof() and you have what you need.
The raw_pdu approach might actually work nicely. Since what you really want is to send an AT command and get the right response back from the gateway. In that sense it is similar to what we do for SDP and AVRCP. Of course you need to have also a preamble for the whole SLC setup. And in addition you want to test the stream handling by for example sending an AT command one byte at a time.
Regards
Marcel
^ permalink raw reply
* Re: [PATCH] Bluetooth: Stop BCSP/H5 timer before cleaning up
From: Johan Hedberg @ 2014-03-04 9:05 UTC (permalink / raw)
To: Michael Knudsen; +Cc: linux-bluetooth
In-Reply-To: <53158C89.9010200@samsung.com>
Hi Michael,
On Tue, Mar 04, 2014, Michael Knudsen wrote:
> On 03/04/2014 08:14 AM, Johan Hedberg wrote:
> >>>When stopping BCSP/H5, stop the retransmission timer before proceeding
> >>>to clean up packet queues. The previous code had a race condition where
> >>>the timer could trigger after the packet lists and protocol structure
> >>>had been removed which lead to dereferencing NULL or use-after-free bugs.
> >>
> >>No interest?
> >
> >I was just discussing this yesterday with Marcel (that we seem to have
> >forgotten about this patch). The only concern is whether it's safe to
> >sleep in the *_close callbacks (since you use del_timer_sync). Have you
> >verified that this doesn't cause any issues?
>
> Our internal testing was reliably triggering the crash before and
> has been stable since our fix went into local trees. I expected
> sleeping to be fine since the path is in process context, and I
> found that slip uses the same approach:
>
> drivers/net/slip/slip.c:slip_close()
>
> I think I saw other line disciplines that did the same but I don't
> recall which ones.
>
> Btw. if this is committed, there is a small typo in the message I
> used: Instead of ``lead'' it should be ``led''.
Thanks for the confirmation. I've now pushed the patch to the
bluetooth-next tree (with the typo fixed too).
Johan
^ permalink raw reply
* Re: [PATCH v3 1/8] android/ipc: Add Mode parameter to register service command
From: Szymon Janc @ 2014-03-04 9:20 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1393804249-12392-1-git-send-email-szymon.janc@tieto.com>
On Monday 03 of March 2014 00:50:42 Szymon Janc wrote:
> This will allow to run daemon services in non-default mode.
> ---
> android/hal-ipc-api.txt | 6 ++++++
> 1 file changed, 6 insertions(+)
>
> diff --git a/android/hal-ipc-api.txt b/android/hal-ipc-api.txt
> index 0518c2f..6bf9af3 100644
> --- a/android/hal-ipc-api.txt
> +++ b/android/hal-ipc-api.txt
> @@ -124,12 +124,16 @@ Core Service (ID 0)
> Opcode 0x01 - Register module command/response
>
> Command parameters: Service id (1 octet)
> + Mode (1 octet)
> Response parameters: <none>
>
> In case a command is sent for an undeclared service ID, it will
> be rejected. Also there will be no notifications for undeclared
> service ID.
>
> + Valid Mode values: 0x00 = Default Mode
> + 0xXX = as defined by service
> +
> In case of an error, the error response will be returned.
>
> Opcode 0x02 - Unregister module command/response
> @@ -749,6 +753,8 @@ Bluetooth Handsfree HAL (ID 5)
>
> Android HAL name: "handsfree" (BT_PROFILE_HANDSFREE_ID)
>
> + Service modes: 0x01 = Headset Profile only mode
> +
> Opcode 0x00 - Error response
>
> Response parameters: Status (1 octet)
>
Pushed.
--
Best regards,
Szymon Janc
^ permalink raw reply
* [PATCH bluetooth-next] bluetooth: make bluetooth 6lowpan as an option
From: Alexander Aring @ 2014-03-04 9:23 UTC (permalink / raw)
To: marcel
Cc: gustavo, johan.hedberg, davem, linux-bluetooth, netdev,
Alexander Aring
Currently you can have bluetooth 6lowpan without ipv6 enabled. This
doesn't make any sense. With this patch you can disable/enable bluetooth
6lowpan support at compile time.
The current bluetooth 6lowpan implementation doesn't check the return
value of 6lowpan function. Nevertheless I added -EOPNOTSUPP as return value
if 6lowpan bluetooth is disabled.
Signed-off-by: Alexander Aring <alex.aring@gmail.com>
---
net/bluetooth/6lowpan.h | 21 +++++++++++++++++++++
net/bluetooth/Kconfig | 8 +++++++-
net/bluetooth/Makefile | 3 ++-
3 files changed, 30 insertions(+), 2 deletions(-)
diff --git a/net/bluetooth/6lowpan.h b/net/bluetooth/6lowpan.h
index 680eac8..5d281f1 100644
--- a/net/bluetooth/6lowpan.h
+++ b/net/bluetooth/6lowpan.h
@@ -14,13 +14,34 @@
#ifndef __6LOWPAN_H
#define __6LOWPAN_H
+#include <linux/errno.h>
#include <linux/skbuff.h>
#include <net/bluetooth/l2cap.h>
+#if IS_ENABLED(CONFIG_BT_6LOWPAN)
int bt_6lowpan_recv(struct l2cap_conn *conn, struct sk_buff *skb);
int bt_6lowpan_add_conn(struct l2cap_conn *conn);
int bt_6lowpan_del_conn(struct l2cap_conn *conn);
int bt_6lowpan_init(void);
void bt_6lowpan_cleanup(void);
+#else
+static int bt_6lowpan_recv(struct l2cap_conn *conn, struct sk_buff *skb)
+{
+ return -EOPNOTSUPP;
+}
+static int bt_6lowpan_add_conn(struct l2cap_conn *conn)
+{
+ return -EOPNOTSUPP;
+}
+int bt_6lowpan_del_conn(struct l2cap_conn *conn)
+{
+ return -EOPNOTSUPP;
+}
+static int bt_6lowpan_init(void)
+{
+ return -EOPNOTSUPP;
+}
+static void bt_6lowpan_cleanup(void) { }
+#endif
#endif /* __6LOWPAN_H */
diff --git a/net/bluetooth/Kconfig b/net/bluetooth/Kconfig
index 985b560..10c752f 100644
--- a/net/bluetooth/Kconfig
+++ b/net/bluetooth/Kconfig
@@ -12,7 +12,6 @@ menuconfig BT
select CRYPTO_AES
select CRYPTO_ECB
select CRYPTO_SHA256
- select 6LOWPAN_IPHC
help
Bluetooth is low-cost, low-power, short-range wireless technology.
It was designed as a replacement for cables and other short-range
@@ -40,6 +39,13 @@ menuconfig BT
to Bluetooth kernel modules are provided in the BlueZ packages. For
more information, see <http://www.bluez.org/>.
+config BT_6LOWPAN
+ bool "Bluetooth 6LoWPAN support"
+ depends on BT && IPV6
+ select 6LOWPAN_IPHC
+ help
+ IPv6 compression over Bluetooth.
+
source "net/bluetooth/rfcomm/Kconfig"
source "net/bluetooth/bnep/Kconfig"
diff --git a/net/bluetooth/Makefile b/net/bluetooth/Makefile
index 80cb215..ca51246 100644
--- a/net/bluetooth/Makefile
+++ b/net/bluetooth/Makefile
@@ -10,6 +10,7 @@ obj-$(CONFIG_BT_HIDP) += hidp/
bluetooth-y := af_bluetooth.o hci_core.o hci_conn.o hci_event.o mgmt.o \
hci_sock.o hci_sysfs.o l2cap_core.o l2cap_sock.o smp.o sco.o lib.o \
- a2mp.o amp.o 6lowpan.o
+ a2mp.o amp.o
+bluetooth-$(CONFIG_BT_6LOWPAN) += 6lowpan.o
subdir-ccflags-y += -D__CHECK_ENDIAN__
--
1.9.0
^ permalink raw reply related
* Re: [PATCH v2 1/5] android/hal-audio: Add open/close_endpoint helpers
From: Szymon Janc @ 2014-03-04 9:27 UTC (permalink / raw)
To: Andrzej Kaczmarek; +Cc: linux-bluetooth
In-Reply-To: <1393837002-29703-1-git-send-email-andrzej.kaczmarek@tieto.com>
Hi Andrzej,
On Monday 03 of March 2014 09:56:38 Andrzej Kaczmarek wrote:
> ---
> android/hal-audio.c | 117 +++++++++++++++++++++++++++++-----------------------
> 1 file changed, 66 insertions(+), 51 deletions(-)
>
> diff --git a/android/hal-audio.c b/android/hal-audio.c
> index 79a74b8..f6bc998 100644
> --- a/android/hal-audio.c
> +++ b/android/hal-audio.c
> @@ -914,6 +914,70 @@ static void unregister_endpoints(void)
> }
> }
>
> +static int set_blocking(int fd)
> +{
> + int flags;
> +
> + flags = fcntl(fd, F_GETFL, 0);
> + if (flags < 0) {
> + int err = -errno;
> + error("fcntl(F_GETFL): %s (%d)", strerror(-err), -err);
> + return err;
> + }
> +
> + if (fcntl(fd, F_SETFL, flags & ~O_NONBLOCK) < 0) {
> + int err = -errno;
> + error("fcntl(F_SETFL): %s (%d)", strerror(-err), -err);
> + return err;
> + }
> +
> + return 0;
> +}
> +
> +static bool open_endpoint(struct audio_endpoint *ep,
> + struct audio_input_config *cfg)
> +{
> + struct audio_preset *preset;
> + const struct audio_codec *codec;
> + uint16_t mtu;
> + int fd;
> +
> + if (ipc_open_stream_cmd(ep->id, &mtu, &fd, &preset) !=
> + AUDIO_STATUS_SUCCESS)
> + return false;
> +
> + if (set_blocking(fd) < 0)
> + goto failed;
> +
> + ep->fd = fd;
> +
> + codec = ep->codec;
> + codec->init(preset, mtu, &ep->codec_data);
> + codec->get_config(ep->codec_data, cfg);
> +
> + free(preset);
> +
> + return true;
> +
> +failed:
> + close(fd);
> + free(preset);
> +
> + return false;
> +}
> +
> +static void close_endpoint(struct audio_endpoint *ep)
> +{
> + ipc_close_stream_cmd(ep->id);
> + if (ep->fd >= 0) {
> + close(ep->fd);
> + ep->fd = -1;
> + }
> +
> + ep->codec->cleanup(ep->codec_data);
> + ep->codec_data = NULL;
> +}
> +
> static void downmix_to_mono(struct a2dp_stream_out *out, const uint8_t *buffer,
> size_t bytes)
> {
> @@ -1260,26 +1324,6 @@ static int in_remove_audio_effect(const struct audio_stream *stream,
> return -ENOSYS;
> }
>
> -static int set_blocking(int fd)
> -{
> - int flags;
> -
> - flags = fcntl(fd, F_GETFL, 0);
> - if (flags < 0) {
> - int err = -errno;
> - error("fcntl(F_GETFL): %s (%d)", strerror(-err), -err);
> - return err;
> - }
> -
> - if (fcntl(fd, F_SETFL, flags & ~O_NONBLOCK) < 0) {
> - int err = -errno;
> - error("fcntl(F_SETFL): %s (%d)", strerror(-err), -err);
> - return err;
> - }
> -
> - return 0;
> -}
> -
> static int audio_open_output_stream(struct audio_hw_device *dev,
> audio_io_handle_t handle,
> audio_devices_t devices,
> @@ -1290,10 +1334,6 @@ 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;
> - uint16_t mtu;
> - int fd;
>
> out = calloc(1, sizeof(struct a2dp_stream_out));
> if (!out)
> @@ -1321,29 +1361,12 @@ static int audio_open_output_stream(struct audio_hw_device *dev,
> /* TODO: for now we always use endpoint 0 */
> out->ep = &audio_endpoints[0];
>
> - if (ipc_open_stream_cmd(out->ep->id, &mtu, &fd, &preset) !=
> - AUDIO_STATUS_SUCCESS)
> - goto fail;
> -
> - if (!preset || fd < 0)
> - goto fail;
> -
> - if (set_blocking(fd) < 0) {
> - free(preset);
> + if (!open_endpoint(out->ep, &out->cfg))
> goto fail;
> - }
> -
> - out->ep->fd = fd;
> - codec = out->ep->codec;
> -
> - codec->init(preset, mtu, &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);
> -
> if (out->cfg.channels == AUDIO_CHANNEL_OUT_MONO) {
> out->downmix_buf = malloc(FIXED_BUFFER_SIZE / 2);
> if (!out->downmix_buf)
> @@ -1369,18 +1392,10 @@ static void audio_close_output_stream(struct audio_hw_device *dev,
> {
> 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("");
>
> - ipc_close_stream_cmd(ep->id);
> - if (ep->fd >= 0) {
> - close(ep->fd);
> - ep->fd = -1;
> - }
> -
> - ep->codec->cleanup(ep->codec_data);
> - ep->codec_data = NULL;
> + close_endpoint(a2dp_dev->out->ep);
>
> free(out->downmix_buf);
>
All patches in this set are now upstream, thanks.
--
Best regards,
Szymon Janc
^ permalink raw reply
* Re: [PATCH BlueZ 01/16] android/avrcp-lib: Add avrcp_send function
From: Luiz Augusto von Dentz @ 2014-03-04 11:47 UTC (permalink / raw)
To: linux-bluetooth@vger.kernel.org
In-Reply-To: <1393786109-6554-1-git-send-email-luiz.dentz@gmail.com>
Hi,
On Sun, Mar 2, 2014 at 8:48 PM, Luiz Augusto von Dentz
<luiz.dentz@gmail.com> wrote:
> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
>
> This adds avrcp_send function which can be used to response to
> outstanding requests.
> ---
> android/avrcp-lib.c | 27 +++++++++++++++++++++++++++
> android/avrcp-lib.h | 4 +++-
> 2 files changed, 30 insertions(+), 1 deletion(-)
>
> diff --git a/android/avrcp-lib.c b/android/avrcp-lib.c
> index 34eea66..6fed825 100644
> --- a/android/avrcp-lib.c
> +++ b/android/avrcp-lib.c
> @@ -253,6 +253,33 @@ int avrcp_init_uinput(struct avrcp *session, const char *name,
> return avctp_init_uinput(session->conn, name, address);
> }
>
> +int avrcp_send(struct avrcp *session, uint8_t transaction, uint8_t code,
> + uint8_t subunit, uint8_t pdu_id,
> + uint8_t *params, size_t params_len)
> +{
> + struct avrcp_header *pdu = (void *) session->tx_buf;
> + size_t len = sizeof(*pdu);
> +
> + memset(pdu, 0, len);
> +
> + hton24(pdu->company_id, IEEEID_BTSIG);
> + pdu->pdu_id = pdu_id;
> + pdu->packet_type = AVRCP_PACKET_TYPE_SINGLE;
> +
> + if (params_len > 0) {
> + len += params_len;
> +
> + if (len > session->tx_mtu)
> + return -ENOBUFS;
> +
> + memcpy(pdu->params, params, params_len);
> + pdu->params_len = htons(params_len);
> + }
> +
> + return avctp_send_vendordep(session->conn, transaction, code, subunit,
> + session->tx_buf, len);
> +}
> +
> static int avrcp_send_req(struct avrcp *session, uint8_t code, uint8_t subunit,
> uint8_t pdu_id, uint8_t *params,
> size_t params_len, avctp_rsp_cb func,
> diff --git a/android/avrcp-lib.h b/android/avrcp-lib.h
> index 0407cb4..a33bdfe 100644
> --- a/android/avrcp-lib.h
> +++ b/android/avrcp-lib.h
> @@ -102,7 +102,9 @@ void avrcp_set_passthrough_handlers(struct avrcp *session,
> void *user_data);
> int avrcp_init_uinput(struct avrcp *session, const char *name,
> const char *address);
> -
> +int avrcp_send(struct avrcp *session, uint8_t transaction, uint8_t code,
> + uint8_t subunit, uint8_t pdu_id,
> + uint8_t *params, size_t params_len);
> int avrcp_get_capabilities(struct avrcp *session, uint8_t param,
> avctp_rsp_cb func, void *user_data);
> int avrcp_list_player_attributes(struct avrcp *session, avctp_rsp_cb func,
> --
> 1.8.5.3
I went ahead and pushed this sets with a few fixes suggested.
--
Luiz Augusto von Dentz
^ permalink raw reply
* Re: [PATCH 0/6] Initial HAL test AVRCP api support
From: Luiz Augusto von Dentz @ 2014-03-04 11:48 UTC (permalink / raw)
To: Ravi kumar Veeramally; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <CABBYNZLAt520ASue5Ba-BLpdp-+_H911H86fpZ9=qPSwfGkDRg@mail.gmail.com>
Hi Ravi,
On Sun, Mar 2, 2014 at 8:57 PM, Luiz Augusto von Dentz
<luiz.dentz@gmail.com> wrote:
> Hi Ravi,
>
> On Fri, Feb 28, 2014 at 8:58 PM, Ravi kumar Veeramally
> <ravikumar.veeramally@linux.intel.com> wrote:
>> Patchset contains initial AVRCP api support for HAL test.
>>
>> Ravi kumar Veeramally (6):
>> android/client: Add AVRCP get_play_status_rsp support
>> android/client: Add AVRCP get_element_attr_rsp support
>> android/client: Add AVRCP set_volume support
>> android/client: Add AVRCP get_play_status_cb support
>> android/client: Add AVRCP get_element_attr_cb support
>> android/client: Add AVRCP volume_change_cb support
>>
>> android/client/if-rc.c | 151 +++++++++++++++++++++++++++++++++++++++++++++++++
>> 1 file changed, 151 insertions(+)
>>
>> --
>> 1.8.3.2
>
> This doesn't help much with AVRCP since the requests need to be
> responded rather quickly we might need to have them auto responded if
> we really want hal-tester to be usable.
Applied, it turn out to be useful while testing but I did need to add
\n in a few places.
--
Luiz Augusto von Dentz
^ permalink raw reply
* [PATCHv2 01/11] shared/hfp: Fix not freeing cmd_handler prefix
From: Marcin Kraglak @ 2014-03-04 12:28 UTC (permalink / raw)
To: linux-bluetooth
It should be freed while destroy.
---
src/shared/hfp.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/shared/hfp.c b/src/shared/hfp.c
index b10316e..41973b7 100644
--- a/src/shared/hfp.c
+++ b/src/shared/hfp.c
@@ -82,6 +82,8 @@ static void destroy_cmd_handler(void *data)
if (handler->destroy)
handler->destroy(handler->user_data);
+ free(handler->prefix);
+
free(handler);
}
--
1.8.3.1
^ permalink raw reply related
* [PATCHv2 02/11] unit: Initial version of test-hfp
From: Marcin Kraglak @ 2014-03-04 12:28 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1393936106-7493-1-git-send-email-marcin.kraglak@tieto.com>
This is skeleton of hfp unit tests with basic init test
for hfp_gw_new().
Basic test with hfp_gw_new() and hfp_gw_unref.
---
.gitignore | 1 +
Makefile.am | 12 ++++
unit/test-hfp.c | 173 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 186 insertions(+)
create mode 100644 unit/test-hfp.c
diff --git a/.gitignore b/.gitignore
index 94c0c78..6719be8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -84,6 +84,7 @@ unit/test-gdbus-client
unit/test-sdp
unit/test-lib
unit/test-mgmt
+unit/test-hfp
tools/mgmt-tester
tools/smp-tester
tools/gap-tester
diff --git a/Makefile.am b/Makefile.am
index 0c79e58..0107cef 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -293,6 +293,18 @@ unit_test_avrcp_SOURCES = unit/test-avrcp.c \
android/avrcp-lib.c android/avrcp-lib.h
unit_test_avrcp_LDADD = @GLIB_LIBS@ lib/libbluetooth-internal.la
+unit_tests += unit/test-hfp
+
+unit_test_hfp_SOURCES = unit/test-hfp.c \
+ src/shared/io.h src/shared/io-glib.c \
+ src/shared/queue.h src/shared/queue.c \
+ src/shared/util.h src/shared/util.c \
+ src/shared/mgmt.h src/shared/mgmt.c \
+ src/shared/ringbuf.h src/shared/ringbuf.c \
+ src/shared/hfp.h src/shared/hfp.c
+
+unit_test_hfp_LDADD = @GLIB_LIBS@
+
unit_tests += unit/test-gdbus-client
unit_test_gdbus_client_SOURCES = unit/test-gdbus-client.c
diff --git a/unit/test-hfp.c b/unit/test-hfp.c
new file mode 100644
index 0000000..f220569
--- /dev/null
+++ b/unit/test-hfp.c
@@ -0,0 +1,173 @@
+/*
+ *
+ * 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
+ *
+ */
+
+#include <sys/socket.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <glib.h>
+#include "src/shared/hfp.h"
+
+struct context {
+ GMainLoop *main_loop;
+ guint watch_id;
+ int fd_server;
+ int fd_client;
+ struct hfp_gw *hfp;
+ const struct test_data *data;
+ unsigned int pdu_offset;
+};
+
+struct test_pdu {
+ bool valid;
+ const uint8_t *data;
+ size_t size;
+};
+
+struct test_data {
+ char *test_name;
+ struct test_pdu *pdu_list;
+};
+
+#define data(args...) ((const unsigned char[]) { args })
+
+#define raw_pdu(args...) \
+ { \
+ .valid = true, \
+ .data = data(args), \
+ .size = sizeof(data(args)), \
+ }
+
+#define data_end() \
+ { \
+ .valid = false, \
+ }
+
+#define define_test(name, function, args...) \
+ do { \
+ const struct test_pdu pdus[] = { \
+ args, { } \
+ }; \
+ static struct test_data data; \
+ data.test_name = g_strdup(name); \
+ data.pdu_list = g_malloc(sizeof(pdus)); \
+ memcpy(data.pdu_list, pdus, sizeof(pdus)); \
+ g_test_add_data_func(name, &data, function); \
+ } while (0)
+
+static void context_quit(struct context *context)
+{
+ g_main_loop_quit(context->main_loop);
+}
+
+static void test_free(gconstpointer user_data)
+{
+ const struct test_data *data = user_data;
+
+ g_free(data->test_name);
+ g_free(data->pdu_list);
+}
+
+static gboolean test_handler(GIOChannel *channel, GIOCondition cond,
+ gpointer user_data)
+{
+ struct context *context = user_data;
+ const struct test_pdu *pdu;
+
+ pdu = &context->data->pdu_list[context->pdu_offset++];
+
+ g_assert(!pdu->valid);
+ context_quit(context);
+
+ return FALSE;
+}
+
+static struct context *create_context(gconstpointer data)
+{
+ struct context *context = g_new0(struct context, 1);
+ GIOChannel *channel;
+ int err, sv[2];
+
+ context->main_loop = g_main_loop_new(NULL, FALSE);
+ g_assert(context->main_loop);
+
+ err = socketpair(AF_UNIX, SOCK_SEQPACKET | SOCK_CLOEXEC, 0, sv);
+ g_assert(err == 0);
+
+ channel = g_io_channel_unix_new(sv[1]);
+
+ g_io_channel_set_close_on_unref(channel, TRUE);
+ g_io_channel_set_encoding(channel, NULL, NULL);
+ g_io_channel_set_buffered(channel, FALSE);
+
+ context->watch_id = g_io_add_watch(channel,
+ G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
+ test_handler, context);
+ g_assert(context->watch_id > 0);
+
+ g_io_channel_unref(channel);
+
+ context->fd_server = sv[1];
+ context->fd_client = sv[0];
+ context->data = data;
+
+ return context;
+}
+
+static void execute_context(struct context *context)
+{
+ g_main_loop_run(context->main_loop);
+
+ g_source_remove(context->watch_id);
+
+ g_main_loop_unref(context->main_loop);
+
+ test_free(context->data);
+
+ g_free(context);
+}
+
+static void test_init(gconstpointer data)
+{
+ struct context *context = create_context(data);
+
+ context->hfp = hfp_gw_new(context->fd_client);
+
+ g_assert(context->hfp);
+ g_assert(hfp_gw_set_close_on_unref(context->hfp, true));
+
+ hfp_gw_unref(context->hfp);
+
+ execute_context(context);
+}
+
+int main(int argc, char *argv[])
+{
+ g_test_init(&argc, &argv, NULL);
+
+ define_test("/hfp/test_init", test_init, data_end());
+
+ return g_test_run();
+}
--
1.8.3.1
^ permalink raw reply related
* [PATCHv2 03/11] unit/test-hfp: Add /hfp/test_cmd_handler_1
From: Marcin Kraglak @ 2014-03-04 12:28 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1393936106-7493-1-git-send-email-marcin.kraglak@tieto.com>
---
unit/test-hfp.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 47 insertions(+)
diff --git a/unit/test-hfp.c b/unit/test-hfp.c
index f220569..5e16378 100644
--- a/unit/test-hfp.c
+++ b/unit/test-hfp.c
@@ -104,6 +104,20 @@ static gboolean test_handler(GIOChannel *channel, GIOCondition cond,
return FALSE;
}
+static void cmd_handler(const char *command, void *user_data)
+{
+ struct context *context = user_data;
+ const struct test_pdu *pdu;
+ unsigned int cmd_len = strlen(command);
+
+ pdu = &context->data->pdu_list[context->pdu_offset++];
+
+ g_assert(cmd_len == pdu->size);
+ g_assert(!memcmp(command, pdu->data, cmd_len));
+
+ hfp_gw_send_result(context->hfp, HFP_RESULT_ERROR);
+}
+
static struct context *create_context(gconstpointer data)
{
struct context *context = g_new0(struct context, 1);
@@ -146,6 +160,9 @@ static void execute_context(struct context *context)
test_free(context->data);
+ if (context->hfp)
+ hfp_gw_unref(context->hfp);
+
g_free(context);
}
@@ -159,6 +176,32 @@ static void test_init(gconstpointer data)
g_assert(hfp_gw_set_close_on_unref(context->hfp, true));
hfp_gw_unref(context->hfp);
+ context->hfp = NULL;
+
+ execute_context(context);
+}
+
+static void test_command_handler(gconstpointer data)
+{
+ struct context *context = create_context(data);
+ const struct test_pdu *pdu;
+ ssize_t len;
+ bool ret;
+
+ context->hfp = hfp_gw_new(context->fd_client);
+ g_assert(context->hfp);
+
+ pdu = &context->data->pdu_list[context->pdu_offset++];
+
+ ret = hfp_gw_set_close_on_unref(context->hfp, true);
+ g_assert(ret);
+
+ ret = hfp_gw_set_command_handler(context->hfp, cmd_handler,
+ context, NULL);
+ g_assert(ret);
+
+ len = write(context->fd_server, pdu->data, pdu->size);
+ g_assert_cmpint(len, ==, pdu->size);
execute_context(context);
}
@@ -168,6 +211,10 @@ int main(int argc, char *argv[])
g_test_init(&argc, &argv, NULL);
define_test("/hfp/test_init", test_init, data_end());
+ define_test("/hfp/test_cmd_handler_1", test_command_handler,
+ raw_pdu('A', 'T', '+', 'B', 'R', 'S', 'F', '\r'),
+ raw_pdu('A', 'T', '+', 'B', 'R', 'S', 'F'),
+ data_end());
return g_test_run();
}
--
1.8.3.1
^ permalink raw reply related
* [PATCHv2 04/11] unit/test-hfp: Add /hfp/test_cmd_handler_2
From: Marcin Kraglak @ 2014-03-04 12:28 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1393936106-7493-1-git-send-email-marcin.kraglak@tieto.com>
---
unit/test-hfp.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/unit/test-hfp.c b/unit/test-hfp.c
index 5e16378..1a22298 100644
--- a/unit/test-hfp.c
+++ b/unit/test-hfp.c
@@ -215,6 +215,10 @@ int main(int argc, char *argv[])
raw_pdu('A', 'T', '+', 'B', 'R', 'S', 'F', '\r'),
raw_pdu('A', 'T', '+', 'B', 'R', 'S', 'F'),
data_end());
+ define_test("/hfp/test_cmd_handler_2", test_command_handler,
+ raw_pdu('A', 'T', 'D', '1', '2', '3', '4', '\r'),
+ raw_pdu('A', 'T', 'D', '1', '2', '3', '4'),
+ data_end());
return g_test_run();
}
--
1.8.3.1
^ permalink raw reply related
* [PATCHv2 05/11] unit/test-hfp: Add /hfp/test_register_1
From: Marcin Kraglak @ 2014-03-04 12:28 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1393936106-7493-1-git-send-email-marcin.kraglak@tieto.com>
---
unit/test-hfp.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 54 insertions(+)
diff --git a/unit/test-hfp.c b/unit/test-hfp.c
index 1a22298..f202f91 100644
--- a/unit/test-hfp.c
+++ b/unit/test-hfp.c
@@ -44,6 +44,7 @@ struct test_pdu {
bool valid;
const uint8_t *data;
size_t size;
+ enum hfp_gw_cmd_type type;
};
struct test_data {
@@ -65,6 +66,14 @@ struct test_data {
.valid = false, \
}
+#define type_pdu(cmd_type, args...) \
+ { \
+ .valid = true, \
+ .data = data(args), \
+ .size = sizeof(data(args)), \
+ .type = cmd_type, \
+ }
+
#define define_test(name, function, args...) \
do { \
const struct test_pdu pdus[] = { \
@@ -118,6 +127,19 @@ static void cmd_handler(const char *command, void *user_data)
hfp_gw_send_result(context->hfp, HFP_RESULT_ERROR);
}
+static void prefix_handler(struct hfp_gw_result *result,
+ enum hfp_gw_cmd_type type, void *user_data)
+{
+ struct context *context = user_data;
+ const struct test_pdu *pdu;
+
+ pdu = &context->data->pdu_list[context->pdu_offset++];
+
+ g_assert(type == pdu->type);
+
+ hfp_gw_send_result(context->hfp, HFP_RESULT_ERROR);
+}
+
static struct context *create_context(gconstpointer data)
{
struct context *context = g_new0(struct context, 1);
@@ -206,6 +228,33 @@ static void test_command_handler(gconstpointer data)
execute_context(context);
}
+static void test_register(gconstpointer data)
+{
+ struct context *context = create_context(data);
+ const struct test_pdu *pdu;
+ ssize_t len;
+ bool ret;
+
+ context->hfp = hfp_gw_new(context->fd_client);
+ g_assert(context->hfp);
+
+ pdu = &context->data->pdu_list[context->pdu_offset++];
+
+ ret = hfp_gw_set_close_on_unref(context->hfp, true);
+ g_assert(ret);
+
+ ret = hfp_gw_register(context->hfp, prefix_handler, (char *)pdu->data,
+ context, NULL);
+ g_assert(ret);
+
+ pdu = &context->data->pdu_list[context->pdu_offset++];
+
+ len = write(context->fd_server, pdu->data, pdu->size);
+ g_assert_cmpint(len, ==, pdu->size);
+
+ execute_context(context);
+}
+
int main(int argc, char *argv[])
{
g_test_init(&argc, &argv, NULL);
@@ -219,6 +268,11 @@ int main(int argc, char *argv[])
raw_pdu('A', 'T', 'D', '1', '2', '3', '4', '\r'),
raw_pdu('A', 'T', 'D', '1', '2', '3', '4'),
data_end());
+ define_test("/hfp/test_register_1", test_register,
+ raw_pdu('+', 'B', 'R', 'S', 'F', '\0'),
+ raw_pdu('A', 'T', '+', 'B', 'R', 'S', 'F', '\r'),
+ type_pdu(HFP_GW_CMD_TYPE_COMMAND, 0),
+ data_end());
return g_test_run();
}
--
1.8.3.1
^ permalink raw reply related
* [PATCHv2 06/11] unit/test-hfp: Add /hfp/test_register_2
From: Marcin Kraglak @ 2014-03-04 12:28 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1393936106-7493-1-git-send-email-marcin.kraglak@tieto.com>
---
unit/test-hfp.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/unit/test-hfp.c b/unit/test-hfp.c
index f202f91..cb422d4 100644
--- a/unit/test-hfp.c
+++ b/unit/test-hfp.c
@@ -273,6 +273,11 @@ int main(int argc, char *argv[])
raw_pdu('A', 'T', '+', 'B', 'R', 'S', 'F', '\r'),
type_pdu(HFP_GW_CMD_TYPE_COMMAND, 0),
data_end());
+ define_test("/hfp/test_register_2", test_register,
+ raw_pdu('+', 'B', 'R', 'S', 'F', '\0'),
+ raw_pdu('A', 'T', '+', 'B', 'R', 'S', 'F', '=', '\r'),
+ type_pdu(HFP_GW_CMD_TYPE_SET, 0),
+ data_end());
return g_test_run();
}
--
1.8.3.1
^ permalink raw reply related
* [PATCHv2 07/11] unit/test-hfp: Add /hfp/test_register_3
From: Marcin Kraglak @ 2014-03-04 12:28 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1393936106-7493-1-git-send-email-marcin.kraglak@tieto.com>
---
unit/test-hfp.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/unit/test-hfp.c b/unit/test-hfp.c
index cb422d4..a5fe436 100644
--- a/unit/test-hfp.c
+++ b/unit/test-hfp.c
@@ -278,6 +278,11 @@ int main(int argc, char *argv[])
raw_pdu('A', 'T', '+', 'B', 'R', 'S', 'F', '=', '\r'),
type_pdu(HFP_GW_CMD_TYPE_SET, 0),
data_end());
+ define_test("/hfp/test_register_3", test_register,
+ raw_pdu('+', 'B', 'R', 'S', 'F', '\0'),
+ raw_pdu('A', 'T', '+', 'B', 'R', 'S', 'F', '?', '\r'),
+ type_pdu(HFP_GW_CMD_TYPE_READ, 0),
+ data_end());
return g_test_run();
}
--
1.8.3.1
^ permalink raw reply related
* [PATCHv2 08/11] unit/test-hfp: Add /hfp/test_register_4
From: Marcin Kraglak @ 2014-03-04 12:28 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1393936106-7493-1-git-send-email-marcin.kraglak@tieto.com>
---
unit/test-hfp.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/unit/test-hfp.c b/unit/test-hfp.c
index a5fe436..85d3a60 100644
--- a/unit/test-hfp.c
+++ b/unit/test-hfp.c
@@ -283,6 +283,12 @@ int main(int argc, char *argv[])
raw_pdu('A', 'T', '+', 'B', 'R', 'S', 'F', '?', '\r'),
type_pdu(HFP_GW_CMD_TYPE_READ, 0),
data_end());
+ define_test("/hfp/test_register_4", test_register,
+ raw_pdu('+', 'B', 'R', 'S', 'F', '\0'),
+ raw_pdu('A', 'T', '+', 'B', 'R', 'S', 'F', '=', '?',
+ '\r'),
+ type_pdu(HFP_GW_CMD_TYPE_TEST, 0),
+ data_end());
return g_test_run();
}
--
1.8.3.1
^ permalink raw reply related
* [PATCHv2 09/11] unit/test-hfp: Add /hfp/test_register_5
From: Marcin Kraglak @ 2014-03-04 12:28 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1393936106-7493-1-git-send-email-marcin.kraglak@tieto.com>
---
unit/test-hfp.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/unit/test-hfp.c b/unit/test-hfp.c
index 85d3a60..546a239 100644
--- a/unit/test-hfp.c
+++ b/unit/test-hfp.c
@@ -289,6 +289,11 @@ int main(int argc, char *argv[])
'\r'),
type_pdu(HFP_GW_CMD_TYPE_TEST, 0),
data_end());
+ define_test("/hfp/test_register_5", test_register,
+ raw_pdu('D', '\0'),
+ raw_pdu('A', 'T', 'D', '1', '2', '3', '4', '5', '\r'),
+ type_pdu(HFP_GW_CMD_TYPE_SET, 0),
+ data_end());
return g_test_run();
}
--
1.8.3.1
^ permalink raw reply related
* [PATCHv2 10/11] unit/test-hfp: Add /hfp/test_fragmented_1
From: Marcin Kraglak @ 2014-03-04 12:28 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1393936106-7493-1-git-send-email-marcin.kraglak@tieto.com>
---
unit/test-hfp.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 47 insertions(+)
diff --git a/unit/test-hfp.c b/unit/test-hfp.c
index 546a239..5218a2b 100644
--- a/unit/test-hfp.c
+++ b/unit/test-hfp.c
@@ -45,6 +45,7 @@ struct test_pdu {
const uint8_t *data;
size_t size;
enum hfp_gw_cmd_type type;
+ bool fragmented;
};
struct test_data {
@@ -74,6 +75,14 @@ struct test_data {
.type = cmd_type, \
}
+#define frg_pdu(args...) \
+ { \
+ .valid = true, \
+ .data = data(args), \
+ .size = sizeof(data(args)), \
+ .fragmented = true, \
+ }
+
#define define_test(name, function, args...) \
do { \
const struct test_pdu pdus[] = { \
@@ -255,6 +264,40 @@ static void test_register(gconstpointer data)
execute_context(context);
}
+static gboolean send_pdu(gpointer user_data)
+{
+ struct context *context = user_data;
+ const struct test_pdu *pdu;
+ ssize_t len;
+
+ pdu = &context->data->pdu_list[context->pdu_offset++];
+
+ len = write(context->fd_server, pdu->data, pdu->size);
+ g_assert_cmpint(len, ==, pdu->size);
+
+ pdu = &context->data->pdu_list[context->pdu_offset];
+ if (pdu->fragmented)
+ g_idle_add(send_pdu, context);
+
+ return FALSE;
+}
+
+static void test_fragmented(gconstpointer data)
+{
+ struct context *context = create_context(data);
+ bool ret;
+
+ context->hfp = hfp_gw_new(context->fd_client);
+ g_assert(context->hfp);
+
+ ret = hfp_gw_set_close_on_unref(context->hfp, true);
+ g_assert(ret);
+
+ g_idle_add(send_pdu, context);
+
+ execute_context(context);
+}
+
int main(int argc, char *argv[])
{
g_test_init(&argc, &argv, NULL);
@@ -294,6 +337,10 @@ int main(int argc, char *argv[])
raw_pdu('A', 'T', 'D', '1', '2', '3', '4', '5', '\r'),
type_pdu(HFP_GW_CMD_TYPE_SET, 0),
data_end());
+ define_test("/hfp/test_fragmented_1", test_fragmented,
+ frg_pdu('A'), frg_pdu('T'), frg_pdu('+'), frg_pdu('B'),
+ frg_pdu('R'), frg_pdu('S'), frg_pdu('F'), frg_pdu('\r'),
+ data_end());
return g_test_run();
}
--
1.8.3.1
^ permalink raw reply related
* [PATCHv2 11/11] shared/hfp: Don't try read uninitialized data in ringbuffer
From: Marcin Kraglak @ 2014-03-04 12:28 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1393936106-7493-1-git-send-email-marcin.kraglak@tieto.com>
Don't try to read uninitialized value if '\r' was not found.
This is call stack from valgrind:
/hfp/test_fragmented_1: ==24869== Conditional jump or move depends on uninitialised value(s)
==24869== at 0x400A5E4: memchr (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==24869== by 0x804D24D: can_read_data (hfp.c:359)
==24869== by 0x804A6E2: read_callback (io-glib.c:168)
==24869== by 0x4108BFD5: ??? (in /usr/lib/libglib-2.0.so.0.3600.4)
==24869== by 0x410470E5: g_main_context_dispatch (in /usr/lib/libglib-2.0.so.0.3600.4)
==24869== by 0x41047497: ??? (in /usr/lib/libglib-2.0.so.0.3600.4)
==24869== by 0x41047912: g_main_loop_run (in /usr/lib/libglib-2.0.so.0.3600.4)
==24869== by 0x8049EE0: execute_context (test-hfp.c:186)
==24869== by 0x4106CBC1: ??? (in /usr/lib/libglib-2.0.so.0.3600.4)
==24869== by 0x4106CD5B: ??? (in /usr/lib/libglib-2.0.so.0.3600.4)
==24869== by 0x4106D0E0: g_test_run_suite (in /usr/lib/libglib-2.0.so.0.3600.4)
==24869== by 0x4106D13C: g_test_run (in /usr/lib/libglib-2.0.so.0.3600.4)
---
src/shared/hfp.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/src/shared/hfp.c b/src/shared/hfp.c
index 41973b7..2ca1272 100644
--- a/src/shared/hfp.c
+++ b/src/shared/hfp.c
@@ -352,6 +352,12 @@ static void process_input(struct hfp_gw *hfp)
char *str2;
size_t len2;
+ /* If there is no more data in ringbuffer,
+ * it's just an incomplete command.
+ */
+ if (len == ringbuf_len(hfp->read_buf))
+ return;
+
str2 = ringbuf_peek(hfp->read_buf, len, &len2);
if (!str2)
return;
--
1.8.3.1
^ permalink raw reply related
* [PATCH BlueZ] AVCTP: Fix sending wrong response format
From: Luiz Augusto von Dentz @ 2014-03-04 13:08 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Reject and Not Implemented responses of PASS THROUGH commands shall
contain the data of the previous frame accourding to AVC Panel Subunit
specification page 87.
---
android/avctp.c | 4 ++--
profiles/audio/avctp.c | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/android/avctp.c b/android/avctp.c
index abf9449..9232cfa 100644
--- a/android/avctp.c
+++ b/android/avctp.c
@@ -322,7 +322,7 @@ static ssize_t handle_panel_passthrough(struct avctp *session,
if (*code != AVC_CTYPE_CONTROL || *subunit != AVC_SUBUNIT_PANEL) {
*code = AVC_CTYPE_REJECTED;
- return 0;
+ return operand_count;
}
if (operand_count == 0)
@@ -394,7 +394,7 @@ static ssize_t handle_panel_passthrough(struct avctp *session,
DBG("AV/C: unknown button 0x%02X %s",
operands[0] & 0x7F, status);
*code = AVC_CTYPE_NOT_IMPLEMENTED;
- return 0;
+ return operand_count;
}
done:
diff --git a/profiles/audio/avctp.c b/profiles/audio/avctp.c
index 28c7685..f88e634 100644
--- a/profiles/audio/avctp.c
+++ b/profiles/audio/avctp.c
@@ -342,7 +342,7 @@ static size_t handle_panel_passthrough(struct avctp *session,
if (*code != AVC_CTYPE_CONTROL || *subunit != AVC_SUBUNIT_PANEL) {
*code = AVC_CTYPE_REJECTED;
- return 0;
+ return operand_count;
}
if (operand_count == 0)
@@ -408,7 +408,7 @@ static size_t handle_panel_passthrough(struct avctp *session,
DBG("AV/C: unknown button 0x%02X %s",
operands[0] & 0x7F, status);
*code = AVC_CTYPE_NOT_IMPLEMENTED;
- return 0;
+ return operand_count;
}
done:
--
1.8.5.3
^ permalink raw reply related
* [PATCHv2 00/10] AVRCP test patches rebased
From: Andrei Emeltchenko @ 2014-03-04 14:02 UTC (permalink / raw)
To: linux-bluetooth
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
This is rebased version of my previous patch set rebased after
latest modifications of avrcp-lib.
Andrei Emeltchenko (10):
avrcp: Fix possible buffer overflow
unit/avrcp: Add /TP/PAS/BV-06-C test
unit/avrcp: Add /TP/PAS/BV-08-C test
android/avrcp: Add avrcp_get_current_player_value() function
unit/avrcp: Add /TP/PAS/BV-09-C test
unit/avrcp: Add /TP/PAS/BV-10-C test
android/avrcp: Add avrcp_set_player_value() function
unit/avrcp: Add /TP/PAS/BV-11-C test
unit/avrcp: Add /TP/PAS/BI-01-C test
doc: Update test coverage document
android/avrcp-lib.c | 39 +++++++++++++
android/avrcp-lib.h | 14 +++++
doc/test-coverage.txt | 2 +-
profiles/audio/avrcp.c | 3 +
unit/test-avrcp.c | 156 +++++++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 213 insertions(+), 1 deletion(-)
--
1.8.3.2
^ permalink raw reply
* [PATCHv2 01/10] avrcp: Fix possible buffer overflow
From: Andrei Emeltchenko @ 2014-03-04 14:02 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1393941735-12187-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
This fixes static analysers warnings.
---
profiles/audio/avrcp.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/profiles/audio/avrcp.c b/profiles/audio/avrcp.c
index bca2fc8..aa932e0 100644
--- a/profiles/audio/avrcp.c
+++ b/profiles/audio/avrcp.c
@@ -1909,6 +1909,9 @@ static void avrcp_get_current_player_value(struct avrcp *session,
struct avrcp_header *pdu = (void *) buf;
uint16_t length = AVRCP_HEADER_LENGTH + count + 1;
+ if (count > AVRCP_ATTRIBUTE_LAST)
+ return;
+
memset(buf, 0, sizeof(buf));
set_company_id(pdu->company_id, IEEEID_BTSIG);
--
1.8.3.2
^ permalink raw reply related
* [PATCHv2 02/10] unit/avrcp: Add /TP/PAS/BV-06-C test
From: Andrei Emeltchenko @ 2014-03-04 14:02 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1393941735-12187-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Test verifies that the list player application setting values response
issued from the Target.
---
unit/test-avrcp.c | 29 +++++++++++++++++++++++++++++
1 file changed, 29 insertions(+)
diff --git a/unit/test-avrcp.c b/unit/test-avrcp.c
index 8119b53..d33a459 100644
--- a/unit/test-avrcp.c
+++ b/unit/test-avrcp.c
@@ -333,6 +333,22 @@ static ssize_t avrcp_handle_get_player_attr_text(struct avrcp *session,
return 1;
}
+static ssize_t avrcp_handle_list_player_values(struct avrcp *session,
+ uint8_t transaction,
+ uint16_t params_len,
+ uint8_t *params,
+ void *user_data)
+{
+ DBG("params[0] %d params_len %d", params[0], params_len);
+
+ if (params_len != 1)
+ return -EINVAL;
+
+ params[0] = 0;
+
+ return 1;
+}
+
static const struct avrcp_control_handler control_handlers[] = {
{ AVRCP_GET_CAPABILITIES,
AVC_CTYPE_STATUS, AVC_CTYPE_STABLE,
@@ -343,6 +359,9 @@ static const struct avrcp_control_handler control_handlers[] = {
{ AVRCP_GET_PLAYER_ATTRIBUTE_TEXT,
AVC_CTYPE_STATUS, AVC_CTYPE_STABLE,
avrcp_handle_get_player_attr_text },
+ { AVRCP_LIST_PLAYER_VALUES,
+ AVC_CTYPE_STATUS, AVC_CTYPE_STABLE,
+ avrcp_handle_list_player_values },
{ },
};
@@ -499,5 +518,15 @@ int main(int argc, char *argv[])
AVRCP_GET_PLAYER_ATTRIBUTE_TEXT,
0x00, 0x00, 0x01, 0x00));
+ define_test("/TP/PAS/BV-06-C", test_server,
+ raw_pdu(0x00, 0x11, 0x0e, 0x01, 0x48, 0x00,
+ 0x00, 0x19, 0x58,
+ AVRCP_LIST_PLAYER_VALUES,
+ 0x00, 0x00, 0x01, 0x00),
+ raw_pdu(0x02, 0x11, 0x0e, 0x0c, 0x48, 0x00,
+ 0x00, 0x19, 0x58,
+ AVRCP_LIST_PLAYER_VALUES,
+ 0x00, 0x00, 0x01, 0x00));
+
return g_test_run();
}
--
1.8.3.2
^ permalink raw reply related
* [PATCHv2 03/10] unit/avrcp: Add /TP/PAS/BV-08-C test
From: Andrei Emeltchenko @ 2014-03-04 14:02 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1393941735-12187-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Test verifies that the get player application setting values response
issued from the Target.
---
unit/test-avrcp.c | 29 +++++++++++++++++++++++++++++
1 file changed, 29 insertions(+)
diff --git a/unit/test-avrcp.c b/unit/test-avrcp.c
index d33a459..a2f554c 100644
--- a/unit/test-avrcp.c
+++ b/unit/test-avrcp.c
@@ -349,6 +349,22 @@ static ssize_t avrcp_handle_list_player_values(struct avrcp *session,
return 1;
}
+static ssize_t avrcp_handle_get_player_value_text(struct avrcp *session,
+ uint8_t transaction,
+ uint16_t params_len,
+ uint8_t *params,
+ void *user_data)
+{
+ DBG("");
+
+ if (params_len != 1)
+ return -EINVAL;
+
+ params[0] = 0;
+
+ return 1;
+}
+
static const struct avrcp_control_handler control_handlers[] = {
{ AVRCP_GET_CAPABILITIES,
AVC_CTYPE_STATUS, AVC_CTYPE_STABLE,
@@ -362,6 +378,9 @@ static const struct avrcp_control_handler control_handlers[] = {
{ AVRCP_LIST_PLAYER_VALUES,
AVC_CTYPE_STATUS, AVC_CTYPE_STABLE,
avrcp_handle_list_player_values },
+ { AVRCP_GET_PLAYER_VALUE_TEXT,
+ AVC_CTYPE_STATUS, AVC_CTYPE_STABLE,
+ avrcp_handle_get_player_value_text },
{ },
};
@@ -528,5 +547,15 @@ int main(int argc, char *argv[])
AVRCP_LIST_PLAYER_VALUES,
0x00, 0x00, 0x01, 0x00));
+ define_test("/TP/PAS/BV-08-C", test_server,
+ raw_pdu(0x00, 0x11, 0x0e, 0x01, 0x48, 0x00,
+ 0x00, 0x19, 0x58,
+ AVRCP_GET_PLAYER_VALUE_TEXT,
+ 0x00, 0x00, 0x01, 0x00),
+ raw_pdu(0x02, 0x11, 0x0e, 0x0c, 0x48, 0x00,
+ 0x00, 0x19, 0x58,
+ AVRCP_GET_PLAYER_VALUE_TEXT,
+ 0x00, 0x00, 0x01, 0x00));
+
return g_test_run();
}
--
1.8.3.2
^ permalink raw reply related
* [PATCHv2 04/10] android/avrcp: Add avrcp_get_current_player_value() function
From: Andrei Emeltchenko @ 2014-03-04 14:02 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1393941735-12187-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
---
android/avrcp-lib.c | 20 ++++++++++++++++++++
android/avrcp-lib.h | 11 +++++++++++
2 files changed, 31 insertions(+)
diff --git a/android/avrcp-lib.c b/android/avrcp-lib.c
index dfd6fa3..8f18b9c 100644
--- a/android/avrcp-lib.c
+++ b/android/avrcp-lib.c
@@ -384,3 +384,23 @@ int avrcp_register_notification_rsp(struct avrcp *session, uint8_t transaction,
AVC_SUBUNIT_PANEL, AVRCP_REGISTER_NOTIFICATION,
params, params_len);
}
+
+int avrcp_get_current_player_value(struct avrcp *session, uint8_t *attributes,
+ uint8_t attr_count, avctp_rsp_cb func,
+ void *user_data)
+
+{
+ uint8_t buf[AVRCP_ATTRIBUTE_LAST + 1];
+
+ if (attr_count > AVRCP_ATTRIBUTE_LAST)
+ return -EINVAL;
+
+ if (attributes && attr_count) {
+ buf[0] = attr_count;
+ memcpy(buf + 1, attributes, attr_count);
+ }
+
+ return avrcp_send_req(session, AVC_CTYPE_STATUS, AVC_SUBUNIT_PANEL,
+ AVRCP_GET_CURRENT_PLAYER_VALUE, buf,
+ attr_count + 1, func, user_data);
+}
diff --git a/android/avrcp-lib.h b/android/avrcp-lib.h
index 7185fb6..5e396bb 100644
--- a/android/avrcp-lib.h
+++ b/android/avrcp-lib.h
@@ -75,6 +75,14 @@
#define CAP_COMPANY_ID 0x02
#define CAP_EVENTS_SUPPORTED 0x03
+/* Player Attributes */
+#define AVRCP_ATTRIBUTE_ILEGAL 0x00
+#define AVRCP_ATTRIBUTE_EQUALIZER 0x01
+#define AVRCP_ATTRIBUTE_REPEAT_MODE 0x02
+#define AVRCP_ATTRIBUTE_SHUFFLE 0x03
+#define AVRCP_ATTRIBUTE_SCAN 0x04
+#define AVRCP_ATTRIBUTE_LAST AVRCP_ATTRIBUTE_SCAN
+
/* Company IDs for vendor dependent commands */
#define IEEEID_BTSIG 0x001958
@@ -138,3 +146,6 @@ int avrcp_get_element_attrs_rsp(struct avrcp *session, uint8_t transaction,
int avrcp_register_notification_rsp(struct avrcp *session, uint8_t transaction,
uint8_t code, uint8_t *params,
size_t params_len);
+int avrcp_get_current_player_value(struct avrcp *session, uint8_t *attributes,
+ uint8_t attr_count, avctp_rsp_cb func,
+ void *user_data);
--
1.8.3.2
^ permalink raw reply related
* [PATCHv2 05/10] unit/avrcp: Add /TP/PAS/BV-09-C test
From: Andrei Emeltchenko @ 2014-03-04 14:02 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1393941735-12187-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Test verifies that get current player application setting value command
issued from the Controller.
---
unit/test-avrcp.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/unit/test-avrcp.c b/unit/test-avrcp.c
index a2f554c..a849be3 100644
--- a/unit/test-avrcp.c
+++ b/unit/test-avrcp.c
@@ -412,6 +412,14 @@ static void test_client(gconstpointer data)
avrcp_get_player_attribute_text(context->session, NULL, 0,
NULL, NULL);
+ if (g_str_equal(context->data->test_name, "/TP/PAS/BV-09-C")) {
+ uint8_t attributes[2] = { AVRCP_ATTRIBUTE_EQUALIZER,
+ AVRCP_ATTRIBUTE_REPEAT_MODE };
+
+ avrcp_get_current_player_value(context->session, attributes,
+ sizeof(attributes), NULL, NULL);
+ }
+
execute_context(context);
}
@@ -557,5 +565,13 @@ int main(int argc, char *argv[])
AVRCP_GET_PLAYER_VALUE_TEXT,
0x00, 0x00, 0x01, 0x00));
+ define_test("/TP/PAS/BV-09-C", test_client,
+ raw_pdu(0x00, 0x11, 0x0e, 0x01, 0x48, 0x00,
+ 0x00, 0x19, 0x58,
+ AVRCP_GET_CURRENT_PLAYER_VALUE,
+ 0x00, 0x00, 0x03, 0x02,
+ AVRCP_ATTRIBUTE_EQUALIZER,
+ AVRCP_ATTRIBUTE_REPEAT_MODE));
+
return g_test_run();
}
--
1.8.3.2
^ permalink raw reply related
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