Linux bluetooth development
 help / color / mirror / Atom feed
* Obexd OPP filesend fails with Windows7 stack
From: Syam Sidhardhan @ 2013-01-11  8:32 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <alpine.DEB.2.02.1204250827200.20357@mathewm-linux>

Hi,

We are using the obexd 0.48 version and testing the obexd.
During testing OPP file send, we found one interoperability
issue with the Windows7 PC stack and some commercialized devices
available in the market.

The issue is: OBEXD file transfer is getting failed
once after the complete file content got transfferd. This is
because of, we do a direct RFCOMM disconection rather than
doing a proper OBEX disconection before.

Does someone can help me a with a fix for this?

hcidump logs:
< ACL data: handle 11 flags 0x00 dlen 15
    L2CAP(d): cid 0x0041 len 11 [psm 3]
      RFCOMM(d): UIH: cr 1 dlci 2 pf 0 ilen 7 fcs 0x9a
        OBEX: Connect cmd(f): len 7 version 1.0 flags 0 mtu 4096
> HCI Event: Number of Completed Packets (0x13) plen 5
    handle 11 packets 2
> ACL data: handle 11 flags 0x02 dlen 9
    L2CAP(d): cid 0x0041 len 5 [psm 3]
      RFCOMM(d): UIH: cr 0 dlci 2 pf 1 ilen 0 fcs 0x5c credits 26
> ACL data: handle 11 flags 0x02 dlen 16
    L2CAP(d): cid 0x0041 len 12 [psm 3]
      RFCOMM(d): UIH: cr 0 dlci 2 pf 1 ilen 7 fcs 0x5c credits 0
        OBEX: Connect rsp(f): status 200 len 7 version 1.0 flags 0 mtu 4096
        Status 200 = Success
< ACL data: handle 11 flags 0x00 dlen 65
    L2CAP(d): cid 0x0041 len 61 [psm 3]
      RFCOMM(d): UIH: cr 1 dlci 2 pf 0 ilen 57 fcs 0x9a
        OBEX: Put cmd(c): len 57
        Name (0x01) = Unicode length 28
        0000: 00 74 00 65 00 73 00 74  00 2d 00 74 00 65 00 78 
.t.e.s.t.-.t.e.x
        0010: 00 74 00 2e 00 74 00 78  00 74 00 00              .t...t.x.t..
        Length (0xc3) = 15
        Body (0x48) = Sequence length 15
        0000: 54 65 73 74 20 44 6f 63  75 6d 65 6e 74 0d 0a     Test 
Document..
> ACL data: handle 11 flags 0x02 dlen 12
    L2CAP(d): cid 0x0041 len 8 [psm 3]
      RFCOMM(d): UIH: cr 0 dlci 2 pf 1 ilen 3 fcs 0x5c credits 1
        OBEX: Put rsp(f): status 100 len 3
< ACL data: handle 11 flags 0x00 dlen 14
    L2CAP(d): cid 0x0041 len 10 [psm 3]
      RFCOMM(d): UIH: cr 1 dlci 2 pf 0 ilen 6 fcs 0x9a
        OBEX: Put cmd(f): len 6 (continue)
        End of Body (0x49) = Sequence length 0
> HCI Event: Number of Completed Packets (0x13) plen 5
    handle 11 packets 2
> ACL data: handle 11 flags 0x02 dlen 12
    L2CAP(d): cid 0x0041 len 8 [psm 3]
      RFCOMM(d): UIH: cr 0 dlci 2 pf 1 ilen 3 fcs 0x5c credits 1
        OBEX: Put rsp(f): status 200 len 3
< ACL data: handle 11 flags 0x00 dlen 8
    L2CAP(d): cid 0x0041 len 4 [psm 3]
      RFCOMM(s): DISC: cr 1 dlci 2 pf 1 ilen 0 fcs 0xb8
> ACL data: handle 11 flags 0x02 dlen 8
    L2CAP(d): cid 0x0041 len 4 [psm 3]
      RFCOMM(s): UA: cr 1 dlci 2 pf 1 ilen 0 fcs 0x92
< ACL data: handle 11 flags 0x00 dlen 8
    L2CAP(d): cid 0x0041 len 4 [psm 3]
      RFCOMM(s): DISC: cr 1 dlci 0 pf 1 ilen 0 fcs 0xfd
< ACL data: handle 11 flags 0x00 dlen 12
    L2CAP(s): Disconn req: dcid 0x0041 scid 0x0041
> HCI Event: Number of Completed Packets (0x13) plen 5
    handle 11 packets 2
> ACL data: handle 11 flags 0x02 dlen 8
    L2CAP(d): cid 0x0041 len 4 [psm 3]
      RFCOMM(s): UA: cr 1 dlci 0 pf 1 ilen 0 fcs 0xd7

Thanks,
Syam. 


^ permalink raw reply

* 57 Bluez-users moderator request(s) waiting
From: bluez-users-bounces @ 2013-01-11  8:30 UTC (permalink / raw)
  To: bluez-users-owner

The Bluez-users@lists.sourceforge.net mailing list has 57 request(s)
waiting for your consideration at:

	https://lists.sourceforge.net/lists/admindb/bluez-users
	
Please attend to this at your earliest convenience.  This notice of
pending requests, if any, will be sent out daily.

Pending subscriptions:
    jiahu@atheros.com (jiahu) Tue Nov  9 05:10:57 2010
    grafologi@tiscali.it (claudiosarda) Wed Nov 17 14:56:49 2010
    ycyan.china@gmail.com (terry_55) Mon Nov 22 05:13:40 2010
    tausif.kts766@gmail.com (Tausif Khan) Sun Dec 26 19:08:37 2010
    ajayembedded@gmail.com (ajaykumar) Mon Jan  3 16:25:20 2011
    tejaswini.purandare@wipro.com Thu Jan  6 11:10:27 2011
    sourabh.gre.ma@gmail.com (SAM) Sun Jan  9 13:08:39 2011
    doina.cristina@gmail.com Fri Feb 25 09:57:30 2011
    xuan_fx@hotmail.com (loafer) Wed Mar  2 02:52:59 2011
    debiswas@cisco.com (Debanjan Biswas) Wed Mar  9 09:29:24 2011
    alex@anwsoft.com.tw (Alex Hsu) Sun Mar 27 01:30:38 2011
    alex@anwsoft.com.tw (Alex Hsu) Sun Mar 27 01:52:01 2011
    loafer_k@sina.com (loafer_k) Thu Mar 31 01:22:00 2011
    rtresidd@tresar-electronics.com.au (Richard) Mon Apr 11 11:40:20 2011
    ylemliu@gmail.com Tue Apr 26 09:17:29 2011
    345017062@qq.com (bluebaby) Tue May 31 11:18:58 2011
    ng@gleike.net (Zanifu) Tue Jun 14 14:29:03 2011
    htcleo@bettercommute.org (Roy) Sat Jun 18 02:51:24 2011
    jcteng@tokenwireless.com Tue Jul  5 07:20:28 2011
    luckysolar@gmail.com (Kyle Lin) Tue Jul  5 09:04:28 2011
    bezui01@live.com (Sarel) Sun Aug  7 04:04:54 2011
    sealeafsun@126.com (KalvinYe) Thu Aug 11 03:22:55 2011
    sunil.kumar5@wipro.com (Sunil) Thu Aug 11 05:52:38 2011
    gmo@passifsemi.com (Gmo) Fri Aug 12 19:36:47 2011
    mjanke@deviceworx.com (Mark) Wed Aug 24 17:18:01 2011
    rhbotha@gmail.com (Rynardt) Fri Sep  2 13:21:09 2011
    liaochaoyun66@gmail.com (T.Liao) Sun Sep  4 10:30:22 2011
    costamagna.valerio@gmail.com Fri Sep 16 13:16:58 2011
    lyj_xp@hotmail.com (Walter Liu ) Sat Oct  1 16:45:28 2011
    wshn13@gmail.com (Wang Shaonan) Tue Nov  8 07:22:46 2011
    pandygui@163.com (pandygui) Sat Nov 12 01:29:22 2011
    wshn13@gmail.com (Wang Shaonan) Thu Dec  8 05:14:21 2011
    delentef@gmail.com (F. Delente) Thu Feb  9 10:44:47 2012
    wofanli@gmail.com (nathan) Tue Mar 13 16:07:26 2012
    mahalakshmi.m@jasmin-infotech.com (dollymaha) Wed Mar 21 07:21:31 2012
    jon1979@sbcglobal.net Thu Mar 22 00:45:57 2012
    marter0574@gmail.com (marter) Thu Apr 12 01:09:49 2012
    yzh2195@arcsoft.com (yu zhihu) Mon Apr 16 02:49:00 2012
    bluez@saltyshells.com (Harry Bennett) Sat Apr 21 12:53:25 2012
    jrs@vt.edu (John S) Wed May  2 00:56:05 2012
    woodsboy.cn@163.com (wanlin) Wed May  2 08:36:47 2012
    ybzhao1989@gmail.com (z7z8th) Mon May 14 06:29:16 2012
    easebone@gmail.com (Luke Huang) Thu May 31 05:40:05 2012
    hikohong@gmail.com (Hiko) Mon Jul  2 01:29:05 2012
    francisco.missael@gmail.com Wed Jul 11 21:50:48 2012
    francisco.missael@gmail.com (Francisco) Wed Jul 25 16:55:36 2012
    nshutchinson@gmail.com (Nick Hutchinson) Tue Jul 31 11:06:12 2012
    karl.wang@mstarsemi.com (karl) Mon Aug  6 06:46:42 2012
    karl.wang@mstarsemi.com (karl.wang) Tue Aug 21 08:47:01 2012
    lcheng@grandstream.com (chenglei) Thu Sep 27 01:09:09 2012
    dshwatrz@gmail.com Wed Oct 17 12:20:35 2012
    zhaojidong6020@163.com (zhaojidong) Thu Oct 25 12:53:31 2012
    yzzq@hotmail.com (yang) Wed Nov  7 09:13:07 2012
    qdtuxt@163.com (xiaotao tu) Wed Dec 12 10:46:14 2012
    embeddedboy@gmail.com (embeddedboy) Wed Dec 19 06:51:20 2012
    bhavesh.soni@indieontech.com (bhavesh) Wed Dec 26 06:36:42 2012
    bhavesh.soni@indieontech.com (bhavesh) Fri Dec 28 09:34:13 2012

^ permalink raw reply

* [PATCH BlueZ 2/2] unit: Add tests for SDP integer Data Elements
From: Anderson Lizardo @ 2013-01-11  1:22 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Anderson Lizardo
In-Reply-To: <1357867322-31384-1-git-send-email-anderson.lizardo@openbossa.org>

SDP_DATA_NIL does not have a value, but its sdp_data_t val field is
zeroed by memset(), so just treat it as UINT8 with zero value to
simplify checking (and not require a separate macro.)

SDP_BOOL is handled by SDP library as a INT8.

SDP_UINT128/SDP_INT128 are just byte arrays converted to host order, so
use memcmp() to compare them (converting from host to network order
first.)
---
 unit/test-sdp.c |   84 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 84 insertions(+)

diff --git a/unit/test-sdp.c b/unit/test-sdp.c
index 7879e58..8c0ce98 100644
--- a/unit/test-sdp.c
+++ b/unit/test-sdp.c
@@ -52,6 +52,7 @@ struct test_data {
 };
 
 #define raw_data(args...) ((const unsigned char[]) { args })
+#define build_u128(args...) ((const uint128_t) { .data = { args } })
 
 #define raw_pdu(args...) \
 	{							\
@@ -768,6 +769,7 @@ static void test_sdp(gconstpointer data)
 static void test_sdp_de_attr(gconstpointer data)
 {
 	const struct test_data_de *test = data;
+	uint128_t u128;
 	sdp_data_t *d;
 	int size = 0;
 
@@ -786,6 +788,39 @@ static void test_sdp_de_attr(gconstpointer data)
 	case SDP_URL_STR16:
 		g_assert_cmpstr(test->expected.val.str, ==, d->val.str);
 		break;
+	case SDP_DATA_NIL:
+	case SDP_UINT8:
+		g_assert_cmpuint(test->expected.val.uint8, ==, d->val.uint8);
+		break;
+	case SDP_UINT16:
+		g_assert_cmpuint(test->expected.val.uint16, ==, d->val.uint16);
+		break;
+	case SDP_UINT32:
+		g_assert_cmpuint(test->expected.val.uint32, ==, d->val.uint32);
+		break;
+	case SDP_UINT64:
+		g_assert_cmpuint(test->expected.val.uint64, ==, d->val.uint64);
+		break;
+	case SDP_BOOL:
+	case SDP_INT8:
+		g_assert_cmpuint(test->expected.val.int8, ==, d->val.int8);
+		break;
+	case SDP_INT16:
+		g_assert_cmpuint(test->expected.val.int16, ==, d->val.int16);
+		break;
+	case SDP_INT32:
+		g_assert_cmpuint(test->expected.val.int32, ==, d->val.int32);
+		break;
+	case SDP_INT64:
+		g_assert_cmpuint(test->expected.val.int64, ==, d->val.int64);
+		break;
+	case SDP_UINT128:
+	case SDP_INT128:
+		/* Expected bytes are in network order */
+		hton128(&d->val.uint128, &u128);
+		g_assert(memcmp(&test->expected.val.uint128, &u128,
+						sizeof(uint128_t)) == 0);
+		break;
 	default:
 		g_assert_not_reached();
 	}
@@ -2774,6 +2809,55 @@ int main(int argc, char *argv[])
 				0x6c, 0x75, 0x65, 0x7a, 0x2e, 0x6f, 0x72, 0x67,
 				0x2f),
 			exp_data(SDP_URL_STR16, str, "http://www.bluez.org/"));
+	define_test_de_attr("NIL",
+			raw_data(0x00),
+			exp_data(SDP_DATA_NIL, uint8, 0));
+	define_test_de_attr("UINT8",
+			raw_data(0x08, 0xff),
+			exp_data(SDP_UINT8, uint8, UINT8_MAX));
+	define_test_de_attr("INT8",
+			raw_data(0x10, 0x80),
+			exp_data(SDP_INT8, int8, INT8_MIN));
+	define_test_de_attr("BOOL",
+			raw_data(0x28, 0x01),
+			exp_data(SDP_BOOL, int8, 1));
+	define_test_de_attr("UINT16",
+			raw_data(0x09, 0xff, 0xff),
+			exp_data(SDP_UINT16, uint16, UINT16_MAX));
+	define_test_de_attr("INT16",
+			raw_data(0x11, 0x80, 0x00),
+			exp_data(SDP_INT16, int16, INT16_MIN));
+	define_test_de_attr("UINT32",
+			raw_data(0x0A, 0xff, 0xff, 0xff, 0xff),
+			exp_data(SDP_UINT32, uint32, UINT32_MAX));
+	define_test_de_attr("INT32",
+			raw_data(0x12, 0x80, 0x00, 0x00, 0x00),
+			exp_data(SDP_INT32, int32, INT32_MIN));
+	define_test_de_attr("UINT64",
+			raw_data(0x0B, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+									0xff),
+			exp_data(SDP_UINT64, uint64, UINT64_MAX));
+	define_test_de_attr("INT64",
+			raw_data(0x13, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+									0x00),
+			exp_data(SDP_INT64, int64, INT64_MIN));
+	/* UINT128/INT128 are just byte arrays parsed as uint128_t */
+	define_test_de_attr("UINT128",
+			raw_data(0x0C, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+					0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+					0xff, 0xff, 0xff),
+			exp_data(SDP_UINT128, uint128,
+				build_u128(0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+						0xff, 0xff, 0xff, 0xff, 0xff,
+						0xff, 0xff, 0xff, 0xff, 0xff)));
+	define_test_de_attr("INT128",
+			raw_data(0x14, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+					0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+					0x00, 0x00, 0x00),
+			exp_data(SDP_INT128, uint128,
+				build_u128(0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+						0x00, 0x00, 0x00, 0x00, 0x00,
+						0x00, 0x00, 0x00, 0x00, 0x00)));
 
 	return g_test_run();
 }
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH BlueZ 1/2] unit: Add {TEXT,URL}_STR{8,16} tests for sdp_extract_attr()
From: Anderson Lizardo @ 2013-01-11  1:22 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Anderson Lizardo

These tests are for valid data. Other tests might be added later to
check for error paths, but will require separate macros.

{TEXT,URL}_STR32 cannot be tested with the same macros because
sdp_extract_attr() does not support them. They will be tested
separately with other SDP library functions.

As example of failure output, if commit
504a0cf46ad89cab8005ce9cffb22e41048f6a30 is reverted for testing, the
STR16 test will fail with:

ERROR:unit/test-sdp.c:776:test_sdp_de_attr: assertion failed
(test->input_size == size): (7 == 11)
---
 unit/test-sdp.c |   78 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 78 insertions(+)

diff --git a/unit/test-sdp.c b/unit/test-sdp.c
index 77a4c6c..7879e58 100644
--- a/unit/test-sdp.c
+++ b/unit/test-sdp.c
@@ -85,6 +85,29 @@ struct test_data {
 #define define_ssa(name, args...) define_test("/TP/SERVER/SSA/" name, 48, args)
 #define define_brw(name, args...) define_test("/TP/SERVER/BRW/" name, 672, args)
 
+/* SDP Data Element (DE) tests */
+struct test_data_de {
+	const void *input_data;
+	size_t input_size;
+	sdp_data_t expected;
+};
+
+#define exp_data(_dtd, val_type, val_data) \
+	((const sdp_data_t) {			\
+		.dtd = _dtd,			\
+		.val.val_type = val_data,	\
+	})
+
+#define define_test_de_attr(name, input, exp) \
+	do {								\
+		static struct test_data_de data;			\
+		data.input_data = input;				\
+		data.input_size = sizeof(input);			\
+		data.expected = exp;					\
+		g_test_add_data_func("/sdp/DE/ATTR/" name, &data,	\
+						test_sdp_de_attr);	\
+	} while (0)
+
 struct context {
 	GMainLoop *main_loop;
 	guint server_source;
@@ -742,6 +765,34 @@ static void test_sdp(gconstpointer data)
 	g_free(test->pdu_list);
 }
 
+static void test_sdp_de_attr(gconstpointer data)
+{
+	const struct test_data_de *test = data;
+	sdp_data_t *d;
+	int size = 0;
+
+	d = sdp_extract_attr(test->input_data, test->input_size, &size, NULL);
+	g_assert(d != NULL);
+	g_assert_cmpuint(test->input_size, ==, size);
+	g_assert_cmpuint(test->expected.dtd, ==, d->dtd);
+
+	if (g_test_verbose() == TRUE)
+		g_print("DTD=0x%02x\n", d->dtd);
+
+	switch (d->dtd) {
+	case SDP_TEXT_STR8:
+	case SDP_TEXT_STR16:
+	case SDP_URL_STR8:
+	case SDP_URL_STR16:
+		g_assert_cmpstr(test->expected.val.str, ==, d->val.str);
+		break;
+	default:
+		g_assert_not_reached();
+	}
+
+	sdp_data_free(d);
+}
+
 int main(int argc, char *argv[])
 {
 	g_test_init(&argc, &argv, NULL);
@@ -2697,5 +2748,32 @@ int main(int argc, char *argv[])
 			0x08, 0x09, 0x00, 0x01, 0x35, 0x03, 0x19, 0x11,
 			0x06, 0x00));
 
+	/*
+	 * SDP Data Element (DE) tests
+	 *
+	 * Test extraction of valid DEs supported by sdp_extract_attr().
+	 */
+	define_test_de_attr("TEXT_STR8/empty",
+			raw_data(0x25, 0x00),
+			exp_data(SDP_TEXT_STR8, str, ""));
+	define_test_de_attr("TEXT_STR8",
+			raw_data(0x25, 0x04, 0x41, 0x42, 0x43, 0x44),
+			exp_data(SDP_TEXT_STR8, str, "ABCD"));
+	define_test_de_attr("TEXT_STR16",
+			raw_data(0x26, 0x00, 0x04, 0x41, 0x42, 0x43, 0x44),
+			exp_data(SDP_TEXT_STR16, str, "ABCD"));
+	define_test_de_attr("URL_STR8",
+			raw_data(0x45, 0x15, 0x68, 0x74, 0x74, 0x70, 0x3a,
+				0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x62, 0x6c,
+				0x75, 0x65, 0x7a, 0x2e, 0x6f, 0x72, 0x67,
+				0x2f),
+			exp_data(SDP_URL_STR8, str, "http://www.bluez.org/"));
+	define_test_de_attr("URL_STR16",
+			raw_data(0x46, 0x00, 0x15, 0x68, 0x74, 0x74, 0x70,
+				0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x62,
+				0x6c, 0x75, 0x65, 0x7a, 0x2e, 0x6f, 0x72, 0x67,
+				0x2f),
+			exp_data(SDP_URL_STR16, str, "http://www.bluez.org/"));
+
 	return g_test_run();
 }
-- 
1.7.9.5


^ permalink raw reply related

* Re: [PATCH BlueZ 1/2] build: Fix --disable-optimization configure option
From: Marcel Holtmann @ 2013-01-11  0:31 UTC (permalink / raw)
  To: Anderson Lizardo; +Cc: linux-bluetooth
In-Reply-To: <1357659987-4219-1-git-send-email-anderson.lizardo@openbossa.org>

Hi Anderson,

> On commit cc9e4e7cae0379864ea06038d92bf7ecc192bba7, this flag was
> mistakenly replaced with the behavior of the old --enable-fortify
> option.
> 
> This patch restores the "-O0" flag when --disable-optimization is used.
> 
> Unfortunately, this is not enough to disable build optimization. By
> default, autoconf adds -O2 to CFLAGS if the compiler is GCC. AM_CFLAGS
> (where -O0 is added with --disable-optimization) is passed as argument
> to GCC before autoconf CFLAGS, so it is not possible to override the
> default -O2. One solution is to use:
> 
> CFLAGS= ./configure --disable-optimization
> 
> i.e. remove -O2 from CFLAGS, and let autoconf add -O0.
> ---
>  acinclude.m4 |    2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

patch has been applied.

Regards

Marcel



^ permalink raw reply

* Re: [PATCH BlueZ 2/2] attrib: Fix compilation errors when compiled without optimization
From: Marcel Holtmann @ 2013-01-11  0:06 UTC (permalink / raw)
  To: Anderson Lizardo; +Cc: linux-bluetooth
In-Reply-To: <1357659987-4219-2-git-send-email-anderson.lizardo@openbossa.org>

Hi Anderzon,

> Fix these build errors:
> 
> attrib/att.c: In function ‘dec_read_by_grp_req’:
> attrib/att.c:165:10: error: comparison between signed and unsigned
> integer expressions [-Werror=sign-compare]
> attrib/att.c:170:10: error: comparison between signed and unsigned
> integer expressions [-Werror=sign-compare]
> attrib/att.c: In function ‘dec_read_by_type_req’:
> attrib/att.c:393:10: error: comparison between signed and unsigned
> integer expressions [-Werror=sign-compare]
> attrib/att.c:402:10: error: comparison between signed and unsigned
> integer expressions [-Werror=sign-compare]
> ---
>  attrib/att.c |    4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)

patch has been applied.

Regards

Marcel



^ permalink raw reply

* Re: [PATCH neard 1/2] build: Use AM_CPPFLAGS instead of INCLUDES
From: Marcel Holtmann @ 2013-01-10 23:54 UTC (permalink / raw)
  To: Lucas De Marchi; +Cc: linux-bluetooth, linux-nfc
In-Reply-To: <1357831094-13513-1-git-send-email-lucas.demarchi@profusion.mobi>

Hi Lucas,

> Makefile.am:50: warning: 'INCLUDES' is the old name for 'AM_CPPFLAGS' (or '*_CPPFLAGS')
> ---
>  Makefile.am | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

patch has been applied.

Regards

Marcel



^ permalink raw reply

* Re: [PATCH neard 2/2] build: Do not use deprecated AM_CONFIG_HEADER
From: Marcel Holtmann @ 2013-01-10 23:54 UTC (permalink / raw)
  To: Lucas De Marchi; +Cc: linux-bluetooth, linux-nfc
In-Reply-To: <1357831094-13513-2-git-send-email-lucas.demarchi@profusion.mobi>

Hi Lucas,

> The long-obsoleted AM_CONFIG_HEADER macro was removed in automake 1.13.
> Use AC_CONFIG_HEADERS instead.
> ---
>  configure.ac | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

patch has been applied.

Regards

Marcel



^ permalink raw reply

* Re: [PATCH BlueZ v2] build: Fix using DBusBasicValue
From: Marcel Holtmann @ 2013-01-10 23:51 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth
In-Reply-To: <1357837193-10092-1-git-send-email-luiz.dentz@gmail.com>

Hi Luiz,

> DBusBasicValue needs a more recent libdbus so use const void * instead
> ---
> v2: Fix all places
> 
>  tools/mpris-player.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)

I changed the subject to tools: prefix since this is not build system
details. Otherwise, patch has been applied.

Regards

Marcel



^ permalink raw reply

* Re: [PATCH 8/8] Bluetooth: Fix sending incorrect new_settings for mgmt_set_powered
From: Gustavo Padovan @ 2013-01-10 18:31 UTC (permalink / raw)
  To: Johan Hedberg; +Cc: linux-bluetooth
In-Reply-To: <1357738180-4128-9-git-send-email-johan.hedberg@gmail.com>

Hi Johan,

* Johan Hedberg <johan.hedberg@gmail.com> [2013-01-09 15:29:40 +0200]:

> From: Johan Hedberg <johan.hedberg@intel.com>
> 
> The socket from which a mgmt_set_powered command was received should
> only receive the command response but no new_settings event.
> 
> The mgmt_powered() function which is used to handle the situation with
> the HCI_AUTO_OFF flag tries to check for a pending command to know which
> socket to skip the event for, but since the pending command hasn't been
> added this will not happen.
> 
> This patch fixes the issue by adding the pending command for the
> HCI_AUTO_OFF case and thereby ensures that mgmt_powered() will skip the
> right socket when sending the new_settings event, but still send the
> proper response to the socket where the command came from.
> 
> Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
> ---
>  net/bluetooth/mgmt.c |    5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)

Patch has been applied, thanks.

	Gustavo

^ permalink raw reply

* Re: [PATCH 5/8 v2] Bluetooth: Fix returning proper command status for start_discovery
From: Gustavo Padovan @ 2013-01-10 18:30 UTC (permalink / raw)
  To: Johan Hedberg; +Cc: linux-bluetooth
In-Reply-To: <1357822449-10727-1-git-send-email-johan.hedberg@gmail.com>

Hi Johan,

* Johan Hedberg <johan.hedberg@gmail.com> [2013-01-10 14:54:09 +0200]:

> From: Johan Hedberg <johan.hedberg@intel.com>
> 
> Management commands should whenever possible fail with proper command
> status or command complete events. This patch fixes the
> mgmt_start_discovery command to do this for the failure cases where an
> incorrect parameter value was passed to it ("not supported" if the
> parameter value was valid but the controller doesn't support it and
> "invalid params" if it isn't valid at all).
> 
> Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
> ---
> v2: Use proposed logic for testing for not supported parameters
> 
>  net/bluetooth/mgmt.c |   46 ++++++++++++++++++++++++++++++----------------
>  1 file changed, 30 insertions(+), 16 deletions(-)

Patch has been applied. Thanks.

	Gustavo

^ permalink raw reply

* [PATCH BlueZ v2] build: Fix using DBusBasicValue
From: Luiz Augusto von Dentz @ 2013-01-10 16:59 UTC (permalink / raw)
  To: linux-bluetooth

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

DBusBasicValue needs a more recent libdbus so use const void * instead
---
v2: Fix all places

 tools/mpris-player.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/tools/mpris-player.c b/tools/mpris-player.c
index de66f97..246791a 100644
--- a/tools/mpris-player.c
+++ b/tools/mpris-player.c
@@ -151,7 +151,6 @@ static int parse_metadata_entry(DBusMessageIter *entry, const char *key,
 						DBusMessageIter *metadata)
 {
 	DBusMessageIter var;
-	DBusBasicValue value;
 	int type;
 
 	printf("metadata %s found\n", key);
@@ -181,6 +180,8 @@ static int parse_metadata_entry(DBusMessageIter *entry, const char *key,
 		dict_append_array(metadata, key, DBUS_TYPE_STRING, &values, i);
 		dbus_free(values);
 	} else if (dbus_type_is_basic(type)) {
+		const void *value;
+
 		dbus_message_iter_get_basic(&var, &value);
 		dict_append_entry(metadata, key, type, &value);
 	} else
@@ -312,7 +313,7 @@ static int parse_property(DBusConnection *conn, const char *path,
 						DBusMessageIter *properties)
 {
 	DBusMessageIter var;
-	DBusBasicValue value;
+	const void *value;
 	int type;
 
 	printf("property %s found\n", key);
-- 
1.8.0.1


^ permalink raw reply related

* Re: [PATCH BlueZ 13/13 v2] tools: Update mpris-player to register using MPRIS interface
From: Luiz Augusto von Dentz @ 2013-01-10 16:56 UTC (permalink / raw)
  To: Anderson Lizardo; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <CAJdJm_Nu0Mo7wGYWQr547Mat9hqXyygRbgn23p1QnyY3GrYJnA@mail.gmail.com>

Hi Anderson,

On Thu, Jan 10, 2013 at 6:02 PM, Anderson Lizardo
<anderson.lizardo@openbossa.org> wrote:
> Hi Luiz,
>
> On Thu, Jan 10, 2013 at 9:37 AM, Luiz Augusto von Dentz
> <luiz.dentz@gmail.com> wrote:
>> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
>>
>> In addition fix not supporting new APIs for getting the adapter.
>> ---
>
> Got this compilation error after this patch:
>
>   CC     tools/mpris-player.o
> tools/mpris-player.c: In function ‘parse_metadata_entry’:
> tools/mpris-player.c:154:2: error: unknown type name ‘DBusBasicValue’
> tools/mpris-player.c: In function ‘parse_property’:
> tools/mpris-player.c:315:2: error: unknown type name ‘DBusBasicValue’

Just send a fix for this, can you try and let me know if it fix the problem.


--
Luiz Augusto von Dentz

^ permalink raw reply

* [PATCH BlueZ] build: Fix using DBusBasicValue
From: Luiz Augusto von Dentz @ 2013-01-10 16:55 UTC (permalink / raw)
  To: linux-bluetooth

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

DBusBasicValue needs a more recent libdbus so use const void * instead
---
 tools/mpris-player.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/tools/mpris-player.c b/tools/mpris-player.c
index de66f97..bf0f747 100644
--- a/tools/mpris-player.c
+++ b/tools/mpris-player.c
@@ -151,7 +151,6 @@ static int parse_metadata_entry(DBusMessageIter *entry, const char *key,
 						DBusMessageIter *metadata)
 {
 	DBusMessageIter var;
-	DBusBasicValue value;
 	int type;
 
 	printf("metadata %s found\n", key);
@@ -181,6 +180,8 @@ static int parse_metadata_entry(DBusMessageIter *entry, const char *key,
 		dict_append_array(metadata, key, DBUS_TYPE_STRING, &values, i);
 		dbus_free(values);
 	} else if (dbus_type_is_basic(type)) {
+		const void *value;
+
 		dbus_message_iter_get_basic(&var, &value);
 		dict_append_entry(metadata, key, type, &value);
 	} else
-- 
1.8.0.1


^ permalink raw reply related

* Re: [PATCH 5/8 v2] Bluetooth: Fix returning proper command status for start_discovery
From: Marcel Holtmann @ 2013-01-10 16:24 UTC (permalink / raw)
  To: Johan Hedberg; +Cc: linux-bluetooth
In-Reply-To: <1357822449-10727-1-git-send-email-johan.hedberg@gmail.com>

Hi Johan,

> Management commands should whenever possible fail with proper command
> status or command complete events. This patch fixes the
> mgmt_start_discovery command to do this for the failure cases where an
> incorrect parameter value was passed to it ("not supported" if the
> parameter value was valid but the controller doesn't support it and
> "invalid params" if it isn't valid at all).
> 
> Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
> ---
> v2: Use proposed logic for testing for not supported parameters
> 
>  net/bluetooth/mgmt.c |   46 ++++++++++++++++++++++++++++++----------------
>  1 file changed, 30 insertions(+), 16 deletions(-)

Acked-by: Marcel Holtmann <marcel@holtmann.org>

Regards

Marcel



^ permalink raw reply

* Re: [PATCH BlueZ 13/13 v2] tools: Update mpris-player to register using MPRIS interface
From: Anderson Lizardo @ 2013-01-10 16:02 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth
In-Reply-To: <1357825038-21970-13-git-send-email-luiz.dentz@gmail.com>

Hi Luiz,

On Thu, Jan 10, 2013 at 9:37 AM, Luiz Augusto von Dentz
<luiz.dentz@gmail.com> wrote:
> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
>
> In addition fix not supporting new APIs for getting the adapter.
> ---

Got this compilation error after this patch:

  CC     tools/mpris-player.o
tools/mpris-player.c: In function ‘parse_metadata_entry’:
tools/mpris-player.c:154:2: error: unknown type name ‘DBusBasicValue’
tools/mpris-player.c: In function ‘parse_property’:
tools/mpris-player.c:315:2: error: unknown type name ‘DBusBasicValue’

Regards,
-- 
Anderson Lizardo
Instituto Nokia de Tecnologia - INdT
Manaus - Brazil

^ permalink raw reply

* [PATCH neard 2/2] build: Do not use deprecated AM_CONFIG_HEADER
From: Lucas De Marchi @ 2013-01-10 15:18 UTC (permalink / raw)
  To: linux-bluetooth, linux-nfc-request; +Cc: Lucas De Marchi
In-Reply-To: <1357831094-13513-1-git-send-email-lucas.demarchi@profusion.mobi>

The long-obsoleted AM_CONFIG_HEADER macro was removed in automake 1.13.
Use AC_CONFIG_HEADERS instead.
---
 configure.ac | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/configure.ac b/configure.ac
index 59d9a0a..3109192 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2,7 +2,7 @@ AC_PREREQ(2.60)
 AC_INIT(neard, 0.8)
 
 AM_INIT_AUTOMAKE([foreign subdir-objects color-tests])
-AM_CONFIG_HEADER(config.h)
+AC_CONFIG_HEADERS(config.h)
 
 m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
 
-- 
1.8.1


^ permalink raw reply related

* [PATCH neard 1/2] build: Use AM_CPPFLAGS instead of INCLUDES
From: Lucas De Marchi @ 2013-01-10 15:18 UTC (permalink / raw)
  To: linux-bluetooth, linux-nfc-request; +Cc: Lucas De Marchi

Makefile.am:50: warning: 'INCLUDES' is the old name for 'AM_CPPFLAGS' (or '*_CPPFLAGS')
---
 Makefile.am | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Makefile.am b/Makefile.am
index 2dd3517..8c3571e 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -47,7 +47,7 @@ AM_CFLAGS = @GLIB_CFLAGS@ @DBUS_CFLAGS@ @NETLINK_CFLAGS@ $(builtin_cflags) \
 					-DPLUGINDIR=\""$(plugindir)"\" \
 					-DCONFIGDIR=\""$(configdir)\""
 
-INCLUDES = -I$(builddir)/include -I$(builddir)/src -I$(srcdir)/gdbus
+AM_CPPFLAGS = -I$(builddir)/include -I$(builddir)/src -I$(srcdir)/gdbus
 
 CLEANFILES = src/builtin.h $(local_headers)
 
-- 
1.8.1


^ permalink raw reply related

* Re: [PATCH BlueZ 3/3] gitignore: Ignore file generated by Automake 1.13
From: Lucas De Marchi @ 2013-01-10 15:10 UTC (permalink / raw)
  To: Marcel Holtmann; +Cc: linux-bluetooth, Lucas De Marchi
In-Reply-To: <1357277576.19248.130.camel@aeonflux>

On Fri, Jan 4, 2013 at 3:32 AM, Marcel Holtmann <marcel@holtmann.org> wrote:
> Hi Lucas,
>
>> ---
>>  .gitignore | 1 +
>>  1 file changed, 1 insertion(+)
>>
>> diff --git a/.gitignore b/.gitignore
>> index 04c9862..619f492 100644
>> --- a/.gitignore
>> +++ b/.gitignore
>> @@ -25,6 +25,7 @@ ltmain.sh
>>  missing
>>  stamp-h1
>>  autom4te.cache
>> +test-driver
>
> no idea what this is. I do not have that. What is it actually.


it seems to be a helper for running tests in parallel. There's this
while configuring:

parallel-tests: installing './test-driver'


Lucas De Marchi

^ permalink raw reply

* Re: [PATCH BlueZ 1/3] build: Do not use deprecated AM_CONFIG_HEADER
From: Lucas De Marchi @ 2013-01-10 14:59 UTC (permalink / raw)
  To: Vinicius Costa Gomes; +Cc: linux-bluetooth, Lucas De Marchi
In-Reply-To: <20130110144734.GA25196@samus>

On Thu, Jan 10, 2013 at 12:47 PM, Vinicius Costa Gomes
<vinicius.gomes@openbossa.org> wrote:
> Hi Lucas,
>
> On 23:21 Thu 03 Jan, Lucas De Marchi wrote:
>> From: Lucas De Marchi <lucas.de.marchi@gmail.com>
>>
>> The long-obsoleted AM_CONFIG_HEADER macro was removed in automake 1.13.
>> Use AC_CONFIG_HEADERS instead.
>
> I think oFono and neard are still missing this fix. Would you care to
> send it?
>

Sure. Thanks for the prod.


Lucas De Marchi

^ permalink raw reply

* Re: [PATCH BlueZ 1/3] build: Do not use deprecated AM_CONFIG_HEADER
From: Vinicius Costa Gomes @ 2013-01-10 14:47 UTC (permalink / raw)
  To: Lucas De Marchi; +Cc: linux-bluetooth, Lucas De Marchi
In-Reply-To: <1357262465-19231-1-git-send-email-lucas.demarchi@profusion.mobi>

Hi Lucas,

On 23:21 Thu 03 Jan, Lucas De Marchi wrote:
> From: Lucas De Marchi <lucas.de.marchi@gmail.com>
> 
> The long-obsoleted AM_CONFIG_HEADER macro was removed in automake 1.13.
> Use AC_CONFIG_HEADERS instead.

I think oFono and neard are still missing this fix. Would you care to
send it?


Cheers,
-- 
Vinicius

^ permalink raw reply

* [PATCH BlueZ 13/13 v2] tools: Update mpris-player to register using MPRIS interface
From: Luiz Augusto von Dentz @ 2013-01-10 13:37 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1357825038-21970-1-git-send-email-luiz.dentz@gmail.com>

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

In addition fix not supporting new APIs for getting the adapter.
---
 Makefile.tools       |   1 +
 tools/mpris-player.c | 517 ++++++++++++++++++++++++++-------------------------
 2 files changed, 261 insertions(+), 257 deletions(-)

diff --git a/Makefile.tools b/Makefile.tools
index be70f51..bda4465 100644
--- a/Makefile.tools
+++ b/Makefile.tools
@@ -174,6 +174,7 @@ tools_btmgmt_LDADD = lib/libbluetooth-private.la @GLIB_LIBS@
 tools_btiotest_SOURCES = tools/btiotest.c btio/btio.h btio/btio.c
 tools_btiotest_LDADD = lib/libbluetooth-private.la @GLIB_LIBS@
 
+tools_mpris_player_SOURCES = $(gdbus_sources) tools/mpris-player.c
 tools_mpris_player_LDADD = @GLIB_LIBS@ @DBUS_LIBS@
 
 EXTRA_DIST += tools/bdaddr.1
diff --git a/tools/mpris-player.c b/tools/mpris-player.c
index fd26101..de66f97 100644
--- a/tools/mpris-player.c
+++ b/tools/mpris-player.c
@@ -35,25 +35,35 @@
 
 #include <dbus/dbus.h>
 #include <glib.h>
+#include <gdbus/gdbus.h>
 
-static volatile sig_atomic_t __io_canceled = 0;
-static volatile sig_atomic_t __io_terminated = 0;
-static char *adapter = "/org/bluez/hci0";
+#define BLUEZ_BUS_NAME "org.bluez"
+#define BLUEZ_PATH "/org/bluez"
+#define BLUEZ_ADAPTER_INTERFACE "org.bluez.Adapter1"
+#define BLUEZ_MEDIA_INTERFACE "org.bluez.Media1"
+#define MPRIS_PLAYER_INTERFACE "org.mpris.MediaPlayer2.Player"
+#define MPRIS_PLAYER_PATH "/org/mpris/MediaPlayer2"
+
+static GMainLoop *main_loop;
+static GDBusProxy *adapter = NULL;
 static DBusConnection *sys = NULL;
 static DBusConnection *session = NULL;
 
+static void dict_append_entry(DBusMessageIter *dict, const char *key, int type,
+								void *val);
+
 static void sig_term(int sig)
 {
-	__io_canceled = 1;
+	g_main_loop_quit(main_loop);
 }
 
 static DBusMessage *get_all(DBusConnection *conn, const char *name)
 {
 	DBusMessage *msg, *reply;
 	DBusError err;
-	const char *iface = "org.mpris.MediaPlayer2.Player";
+	const char *iface = MPRIS_PLAYER_INTERFACE;
 
-	msg = dbus_message_new_method_call(name, "/org/mpris/MediaPlayer2",
+	msg = dbus_message_new_method_call(name, MPRIS_PLAYER_PATH,
 					DBUS_INTERFACE_PROPERTIES, "GetAll");
 	if (!msg) {
 		fprintf(stderr, "Can't allocate new method call\n");
@@ -70,7 +80,6 @@ static DBusMessage *get_all(DBusConnection *conn, const char *name)
 	dbus_message_unref(msg);
 
 	if (!reply) {
-		fprintf(stderr, "Can't get default adapter\n");
 		if (dbus_error_is_set(&err)) {
 			fprintf(stderr, "%s\n", err.message);
 			dbus_error_free(&err);
@@ -93,23 +102,47 @@ static void append_variant(DBusMessageIter *iter, int type, void *val)
 	dbus_message_iter_close_container(iter, &value);
 }
 
-static void dict_append_entry(DBusMessageIter *dict, const char *key, int type,
-								void *val)
+static void append_array_variant(DBusMessageIter *iter, int type, void *val,
+							int n_elements)
 {
-	DBusMessageIter entry;
-
-	if (type == DBUS_TYPE_STRING) {
-		const char *str = *((const char **) val);
-		if (str == NULL)
-			return;
+	DBusMessageIter variant, array;
+	char type_sig[2] = { type, '\0' };
+	char array_sig[3] = { DBUS_TYPE_ARRAY, type, '\0' };
+
+	dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
+						array_sig, &variant);
+
+	dbus_message_iter_open_container(&variant, DBUS_TYPE_ARRAY,
+						type_sig, &array);
+
+	if (dbus_type_is_fixed(type) == TRUE) {
+		dbus_message_iter_append_fixed_array(&array, type, val,
+							n_elements);
+	} else if (type == DBUS_TYPE_STRING || type == DBUS_TYPE_OBJECT_PATH) {
+		const char ***str_array = val;
+		int i;
+
+		for (i = 0; i < n_elements; i++)
+			dbus_message_iter_append_basic(&array, type,
+							&((*str_array)[i]));
 	}
 
+	dbus_message_iter_close_container(&variant, &array);
+
+	dbus_message_iter_close_container(iter, &variant);
+}
+
+static void dict_append_array(DBusMessageIter *dict, const char *key, int type,
+			void *val, int n_elements)
+{
+	DBusMessageIter entry;
+
 	dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY,
-							NULL, &entry);
+						NULL, &entry);
 
 	dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
 
-	append_variant(&entry, type, val);
+	append_array_variant(&entry, type, val, n_elements);
 
 	dbus_message_iter_close_container(dict, &entry);
 }
@@ -118,6 +151,8 @@ static int parse_metadata_entry(DBusMessageIter *entry, const char *key,
 						DBusMessageIter *metadata)
 {
 	DBusMessageIter var;
+	DBusBasicValue value;
+	int type;
 
 	printf("metadata %s found\n", key);
 
@@ -126,89 +161,35 @@ static int parse_metadata_entry(DBusMessageIter *entry, const char *key,
 
 	dbus_message_iter_recurse(entry, &var);
 
-	if (strcasecmp(key, "xesam:title") == 0) {
-		const char *value;
-
-		if (dbus_message_iter_get_arg_type(&var) !=
-							DBUS_TYPE_STRING)
-			return -EINVAL;
-
-		dbus_message_iter_get_basic(&var, &value);
-		dict_append_entry(metadata, "Title", DBUS_TYPE_STRING,
-								&value);
-	} else if (strcasecmp(key, "xesam:artist") == 0) {
-		const char *value;
-		DBusMessageIter array;
-
-		if (dbus_message_iter_get_arg_type(&var) !=
-							DBUS_TYPE_ARRAY)
-			return -EINVAL;
-
-		dbus_message_iter_recurse(&var, &array);
-
-		if (dbus_message_iter_get_arg_type(&array) !=
-							DBUS_TYPE_STRING)
-			return -EINVAL;
-
-		dbus_message_iter_get_basic(&array, &value);
-		dict_append_entry(metadata, "Artist", DBUS_TYPE_STRING,
-								&value);
-	} else if (strcasecmp(key, "xesam:album") == 0) {
-		const char *value;
-
-		if (dbus_message_iter_get_arg_type(&var) !=
-							DBUS_TYPE_STRING)
-			return -EINVAL;
-
-		dbus_message_iter_get_basic(&var, &value);
-		dict_append_entry(metadata, "Album", DBUS_TYPE_STRING,
-								&value);
-	} else if (strcasecmp(key, "xesam:genre") == 0) {
-		const char *value;
+	type = dbus_message_iter_get_arg_type(&var);
+	if (type == DBUS_TYPE_ARRAY) {
+		char **values;
+		int i;
 		DBusMessageIter array;
 
-		if (dbus_message_iter_get_arg_type(&var) !=
-							DBUS_TYPE_ARRAY)
-			return -EINVAL;
-
 		dbus_message_iter_recurse(&var, &array);
 
-		if (dbus_message_iter_get_arg_type(&array) !=
-							DBUS_TYPE_STRING)
-			return -EINVAL;
-
-		dbus_message_iter_get_basic(&array, &value);
-		dict_append_entry(metadata, "Genre", DBUS_TYPE_STRING,
-								&value);
-	} else if (strcasecmp(key, "mpris:length") == 0) {
-		int64_t usec, msec;
-
-		if (dbus_message_iter_get_arg_type(&var) !=
-							DBUS_TYPE_INT64)
-			return -EINVAL;
-
-		dbus_message_iter_get_basic(&var, &usec);
-		msec = usec / 1000;
-
-		dict_append_entry(metadata, "Duration", DBUS_TYPE_UINT32,
-								&msec);
-	} else if (strcasecmp(key, "xesam:trackNumber") == 0) {
-		int32_t value;
+		values = dbus_malloc0(sizeof(char *) * 8);
 
-		if (dbus_message_iter_get_arg_type(&var) !=
-							DBUS_TYPE_INT32)
-			return -EINVAL;
+		i = 0;
+		while (dbus_message_iter_get_arg_type(&array) !=
+							DBUS_TYPE_INVALID) {
+			dbus_message_iter_get_basic(&array, &(values[i++]));
+			dbus_message_iter_next(&array);
+		}
 
+		dict_append_array(metadata, key, DBUS_TYPE_STRING, &values, i);
+		dbus_free(values);
+	} else if (dbus_type_is_basic(type)) {
 		dbus_message_iter_get_basic(&var, &value);
-
-		dict_append_entry(metadata, "TrackNumber", DBUS_TYPE_UINT32,
-								&value);
-	}
+		dict_append_entry(metadata, key, type, &value);
+	} else
+		return -EINVAL;
 
 	return 0;
 }
 
-static int parse_track(DBusMessageIter *args, DBusMessageIter *metadata)
+static int parse_metadata(DBusMessageIter *args, DBusMessageIter *metadata)
 {
 	DBusMessageIter dict;
 	int ctype;
@@ -243,7 +224,7 @@ static int parse_track(DBusMessageIter *args, DBusMessageIter *metadata)
 	return 0;
 }
 
-static void append_track(DBusMessageIter *iter, DBusMessageIter *dict)
+static void append_metadata(DBusMessageIter *iter, DBusMessageIter *dict)
 {
 	DBusMessageIter value, metadata;
 
@@ -255,12 +236,36 @@ static void append_track(DBusMessageIter *iter, DBusMessageIter *dict)
 			DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
 			DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &metadata);
 
-	parse_track(dict, &metadata);
+	parse_metadata(dict, &metadata);
 
 	dbus_message_iter_close_container(&value, &metadata);
 	dbus_message_iter_close_container(iter, &value);
 }
 
+static void dict_append_entry(DBusMessageIter *dict, const char *key, int type,
+								void *val)
+{
+	DBusMessageIter entry;
+
+	if (type == DBUS_TYPE_STRING) {
+		const char *str = *((const char **) val);
+		if (str == NULL)
+			return;
+	}
+
+	dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY,
+							NULL, &entry);
+
+	dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
+
+	if (strcasecmp(key, "Metadata") == 0)
+		append_metadata(&entry, val);
+	else
+		append_variant(&entry, type, val);
+
+	dbus_message_iter_close_container(dict, &entry);
+}
+
 static dbus_bool_t emit_properties_changed(DBusConnection *conn,
 					const char *path,
 					const char *interface,
@@ -268,7 +273,7 @@ static dbus_bool_t emit_properties_changed(DBusConnection *conn,
 					int type, void *value)
 {
 	DBusMessage *signal;
-	DBusMessageIter iter, dict, entry, array;
+	DBusMessageIter iter, dict, array;
 	dbus_bool_t result;
 
 	signal = dbus_message_new_signal(path, DBUS_INTERFACE_PROPERTIES,
@@ -287,16 +292,7 @@ static dbus_bool_t emit_properties_changed(DBusConnection *conn,
 			DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
 			DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
 
-	dbus_message_iter_open_container(&dict, DBUS_TYPE_DICT_ENTRY, NULL,
-								&entry);
-	dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &name);
-
-	if (strcasecmp(name, "Track") == 0)
-		append_track(&entry, value);
-	else
-		append_variant(&entry, type, value);
-
-	dbus_message_iter_close_container(&dict, &entry);
+	dict_append_entry(&dict, name, type, value);
 
 	dbus_message_iter_close_container(&iter, &dict);
 
@@ -316,6 +312,8 @@ static int parse_property(DBusConnection *conn, const char *path,
 						DBusMessageIter *properties)
 {
 	DBusMessageIter var;
+	DBusBasicValue value;
+	int type;
 
 	printf("property %s found\n", key);
 
@@ -324,65 +322,30 @@ static int parse_property(DBusConnection *conn, const char *path,
 
 	dbus_message_iter_recurse(entry, &var);
 
-	if (strcasecmp(key, "PlaybackStatus") == 0) {
-		const char *value;
-
-		if (dbus_message_iter_get_arg_type(&var) !=
-							DBUS_TYPE_STRING)
-			return -EINVAL;
-
-		dbus_message_iter_get_basic(&var, &value);
-
+	if (strcasecmp(key, "Metadata") == 0) {
 		if (properties)
-			dict_append_entry(properties, "Status",
-						DBUS_TYPE_STRING, &value);
+			dict_append_entry(properties, key,
+						DBUS_TYPE_DICT_ENTRY, &var);
 		else
 			emit_properties_changed(sys, path,
-					"org.bluez.MediaPlayer1", "Status",
-					DBUS_TYPE_STRING, &value);
-	} else if (strcasecmp(key, "Position") == 0) {
-		int64_t usec, msec;
-
-		if (dbus_message_iter_get_arg_type(&var) !=
-							DBUS_TYPE_INT64)
-			return -EINVAL;
+					MPRIS_PLAYER_INTERFACE, key,
+					DBUS_TYPE_DICT_ENTRY, &var);
 
-		dbus_message_iter_get_basic(&var, &usec);
-		msec = usec / 1000;
+		return 0;
+	}
 
-		if (properties)
-			dict_append_entry(properties, "Position",
-						DBUS_TYPE_UINT32, &msec);
-		else
-			emit_properties_changed(sys, path,
-					"org.bluez.MediaPlayer1", "Position",
-					DBUS_TYPE_UINT32, &msec);
-	} else if (strcasecmp(key, "Shuffle") == 0) {
-		dbus_bool_t value;
-		const char *str;
-
-		if (dbus_message_iter_get_arg_type(&var) !=
-							DBUS_TYPE_BOOLEAN)
-			return -EINVAL;
+	type = dbus_message_iter_get_arg_type(&var);
+	if (!dbus_type_is_basic(type))
+		return -EINVAL;
 
-		dbus_message_iter_get_basic(&var, &value);
+	dbus_message_iter_get_basic(&var, &value);
 
-		str = value ? "on" : "off";
-		if (properties)
-			dict_append_entry(properties, "Shuffle",
-						DBUS_TYPE_STRING, &str);
-		else
-			emit_properties_changed(sys, path,
-					"org.bluez.MediaPlayer1", "Shuffle",
-					DBUS_TYPE_STRING, &str);
-	} else if (strcasecmp(key, "Metadata") == 0) {
-		if (properties)
-			parse_track(&var, properties);
-		else
-			emit_properties_changed(sys, path,
-					"org.bluez.MediaPlayer1", "Track",
-					DBUS_TYPE_DICT_ENTRY, &var);
-	}
+	if (properties)
+		dict_append_entry(properties, key, type, &value);
+	else
+		emit_properties_changed(sys, path,
+					MPRIS_PLAYER_INTERFACE, key,
+					type, &value);
 
 	return 0;
 }
@@ -435,12 +398,33 @@ static char *sender2path(const char *sender)
 static DBusHandlerResult player_message(DBusConnection *conn,
 						DBusMessage *msg, void *data)
 {
-	if (dbus_message_is_method_call(msg, "org.bluez.MediaPlayer1",
-								"Release")) {
-		printf("Release\n");
-		exit(1);
+	char *owner = data;
+	dbus_uint32_t serial;
+	DBusMessage *copy, *reply;
+	DBusError err;
+
+	copy = dbus_message_copy(msg);
+	dbus_message_set_destination(copy, owner);
+	reply = dbus_connection_send_with_reply_and_block(session, copy, -1,
+									&err);
+	if (!reply) {
+		if (dbus_error_is_set(&err)) {
+			fprintf(stderr, "%s\n", err.message);
+			dbus_error_free(&err);
+		}
+		dbus_message_unref(copy);
+		return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
 	}
 
+	dbus_message_unref(copy);
+
+	copy = dbus_message_copy(reply);
+	serial = dbus_message_get_serial(msg);
+	dbus_message_set_serial(copy, serial);
+
+	dbus_message_unref(copy);
+	dbus_message_unref(reply);
+
 	return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
 }
 
@@ -455,22 +439,28 @@ static void add_player(DBusConnection *conn, const char *name,
 	DBusMessage *msg;
 	DBusMessageIter iter, args, properties;
 	DBusError err;
-	char *path;
+	char *path, *owner;
 
-	if (!reply)
+	if (!reply || !adapter)
 		return;
 
-	msg = dbus_message_new_method_call("org.bluez", adapter,
-					"org.bluez.Media1",
+	msg = dbus_message_new_method_call(BLUEZ_BUS_NAME,
+					g_dbus_proxy_get_path(adapter),
+					BLUEZ_MEDIA_INTERFACE,
 					"RegisterPlayer");
 	if (!msg) {
 		fprintf(stderr, "Can't allocate new method call\n");
 		return;
 	}
 
+	path = sender2path(sender);
+	dbus_connection_get_object_path_data(sys, path, (void **) &owner);
+
+	if (owner != NULL)
+		goto done;
+
 	dbus_message_iter_init_append(msg, &iter);
 
-	path = sender2path(sender);
 	dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH, &path);
 
 	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
@@ -489,20 +479,25 @@ static void add_player(DBusConnection *conn, const char *name,
 
 	dbus_error_init(&err);
 
+	owner = strdup(sender);
+
+	if (!dbus_connection_register_object_path(sys, path, &player_table,
+								owner)) {
+		fprintf(stderr, "Can't register object path for player\n");
+		free(owner);
+		goto done;
+	}
+
 	reply = dbus_connection_send_with_reply_and_block(sys, msg, -1, &err);
 	if (!reply) {
 		fprintf(stderr, "Can't register player\n");
+		free(owner);
 		if (dbus_error_is_set(&err)) {
 			fprintf(stderr, "%s\n", err.message);
 			dbus_error_free(&err);
 		}
-		goto done;
 	}
 
-	if (!dbus_connection_register_object_path(sys, path, &player_table,
-								NULL))
-		fprintf(stderr, "Can't register object path for agent\n");
-
 done:
 	if (reply)
 		dbus_message_unref(reply);
@@ -515,8 +510,12 @@ static void remove_player(DBusConnection *conn, const char *sender)
 	DBusMessage *msg;
 	char *path;
 
-	msg = dbus_message_new_method_call("org.bluez", adapter,
-					"org.bluez.Media1",
+	if (!adapter)
+		return;
+
+	msg = dbus_message_new_method_call(BLUEZ_BUS_NAME,
+					g_dbus_proxy_get_path(adapter),
+					BLUEZ_MEDIA_INTERFACE,
 					"UnregisterPlayer");
 	if (!msg) {
 		fprintf(stderr, "Can't allocate new method call\n");
@@ -529,12 +528,14 @@ static void remove_player(DBusConnection *conn, const char *sender)
 
 	dbus_connection_send(sys, msg, NULL);
 
+	dbus_connection_unregister_object_path(sys, path);
+
 	dbus_message_unref(msg);
 	g_free(path);
 }
 
-static DBusHandlerResult properties_changed(DBusConnection *conn,
-							DBusMessage *msg)
+static gboolean properties_changed(DBusConnection *conn,
+					DBusMessage *msg, void *user_data)
 {
 	DBusMessageIter iter;
 	const char *iface;
@@ -556,22 +557,14 @@ static DBusHandlerResult properties_changed(DBusConnection *conn,
 
 	g_free(path);
 
-	return DBUS_HANDLER_RESULT_HANDLED;
+	return TRUE;
 }
 
-static DBusHandlerResult session_filter(DBusConnection *conn,
+static gboolean name_owner_changed(DBusConnection *conn,
 						DBusMessage *msg, void *data)
 {
 	const char *name, *old, *new;
 
-	if (dbus_message_is_signal(msg, DBUS_INTERFACE_PROPERTIES,
-						"PropertiesChanged"))
-		return properties_changed(conn, msg);
-
-	if (!dbus_message_is_signal(msg, DBUS_INTERFACE_DBUS,
-						"NameOwnerChanged"))
-		return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-
 	if (!dbus_message_get_args(msg, NULL,
 					DBUS_TYPE_STRING, &name,
 					DBUS_TYPE_STRING, &old,
@@ -592,33 +585,7 @@ static DBusHandlerResult session_filter(DBusConnection *conn,
 		add_player(conn, name, new);
 	}
 
-	return DBUS_HANDLER_RESULT_HANDLED;
-}
-
-static DBusHandlerResult system_filter(DBusConnection *conn,
-						DBusMessage *msg, void *data)
-{
-	const char *name, *old, *new;
-
-	if (!dbus_message_is_signal(msg, DBUS_INTERFACE_DBUS,
-						"NameOwnerChanged"))
-		return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-
-	if (!dbus_message_get_args(msg, NULL,
-					DBUS_TYPE_STRING, &name,
-					DBUS_TYPE_STRING, &old,
-					DBUS_TYPE_STRING, &new,
-					DBUS_TYPE_INVALID)) {
-		fprintf(stderr, "Invalid arguments for NameOwnerChanged signal");
-		return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-	}
-
-	if (!strcmp(name, "org.bluez") && *new == '\0') {
-		fprintf(stderr, "bluetoothd disconnected\n");
-		__io_terminated = 1;
-	}
-
-	return DBUS_HANDLER_RESULT_HANDLED;
+	return TRUE;
 }
 
 static char *get_name_owner(DBusConnection *conn, const char *name)
@@ -645,7 +612,6 @@ static char *get_name_owner(DBusConnection *conn, const char *name)
 	dbus_message_unref(msg);
 
 	if (!reply) {
-		fprintf(stderr, "Can't find adapter %s\n", adapter);
 		if (dbus_error_is_set(&err)) {
 			fprintf(stderr, "%s\n", err.message);
 			dbus_error_free(&err);
@@ -698,6 +664,8 @@ static void parse_list_names(DBusConnection *conn, DBusMessageIter *args)
 		if (owner == NULL)
 			goto next;
 
+		printf("player %s at %s found\n", name, owner);
+
 		add_player(conn, name, owner);
 
 		g_free(owner);
@@ -727,7 +695,6 @@ static void list_names(DBusConnection *conn)
 	dbus_message_unref(msg);
 
 	if (!reply) {
-		fprintf(stderr, "Can't find adapter %s\n", adapter);
 		if (dbus_error_is_set(&err)) {
 			fprintf(stderr, "%s\n", err.message);
 			dbus_error_free(&err);
@@ -746,29 +713,71 @@ static void list_names(DBusConnection *conn)
 
 static void usage(void)
 {
-	printf("Bluetooth player ver %s\n\n", VERSION);
+	printf("Bluetooth mpris-player ver %s\n\n", VERSION);
 
-	printf("Usage:\n"
-		"\tplayer [--adapter adapter id]\n"
-		"\n");
+	printf("Usage:\n");
 }
 
 static struct option main_options[] = {
-	{ "adapter",	1, 0, 'a' },
 	{ 0, 0, 0, 0 }
 };
 
+static void connect_handler(DBusConnection *connection, void *user_data)
+{
+	printf("org.bluez appeared\n");
+}
+
+static void disconnect_handler(DBusConnection *connection, void *user_data)
+{
+	printf("org.bluez disappeared\n");
+}
+
+static void proxy_added(GDBusProxy *proxy, void *user_data)
+{
+	const char *interface;
+
+	if (adapter != NULL)
+		return;
+
+	interface = g_dbus_proxy_get_interface(proxy);
+
+	if (!strcmp(interface, BLUEZ_ADAPTER_INTERFACE)) {
+		printf("Bluetooth Adapter %s found\n",
+						g_dbus_proxy_get_path(proxy));
+		adapter = proxy;
+		list_names(session);
+	}
+}
+
+static void proxy_removed(GDBusProxy *proxy, void *user_data)
+{
+	const char *interface;
+
+	if (adapter == NULL)
+		return;
+
+	interface = g_dbus_proxy_get_interface(proxy);
+
+	if (strcmp(interface, BLUEZ_ADAPTER_INTERFACE))
+		return;
+
+	if (adapter != proxy)
+		return;
+
+	printf("Bluetooth Adapter %s removed\n", g_dbus_proxy_get_path(proxy));
+	adapter = NULL;
+}
+
 int main(int argc, char *argv[])
 {
+	GDBusClient *client;
+	guint owner_watch, properties_watch;
 	struct sigaction sa;
-	char match[128];
 	int opt;
 
-	while ((opt = getopt_long(argc, argv, "+a,h", main_options, NULL)) != EOF) {
+	while ((opt = getopt_long(argc, argv, "h", main_options,
+							NULL)) != EOF) {
 		switch(opt) {
-		case '1':
-			adapter = optarg;
-			break;
 		case 'h':
 			usage();
 			exit(0);
@@ -777,48 +786,31 @@ int main(int argc, char *argv[])
 		}
 	}
 
-	sys = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
+	main_loop = g_main_loop_new(NULL, FALSE);
+
+	sys = g_dbus_setup_bus(DBUS_BUS_SYSTEM, NULL, NULL);
 	if (!sys) {
 		fprintf(stderr, "Can't get on system bus");
 		exit(1);
 	}
 
-	if (!dbus_connection_add_filter(sys, system_filter, NULL, NULL)) {
-		fprintf(stderr, "Can't add signal filter");
-		exit(1);
-	}
-
-	snprintf(match, sizeof(match),
-			"interface=%s,member=NameOwnerChanged,arg0=%s",
-			DBUS_INTERFACE_DBUS, "org.bluez");
-
-	dbus_bus_add_match(sys, match, NULL);
-
-	session = dbus_bus_get(DBUS_BUS_SESSION, NULL);
+	session = g_dbus_setup_bus(DBUS_BUS_SESSION, NULL, NULL);
 	if (!session) {
 		fprintf(stderr, "Can't get on session bus");
 		exit(1);
 	}
 
-	if (!dbus_connection_add_filter(session, session_filter, NULL, NULL)) {
-		fprintf(stderr, "Can't add signal filter");
-		exit(1);
-	}
-
-	snprintf(match, sizeof(match),
-			"interface=%s,member=NameOwnerChanged",
-			DBUS_INTERFACE_DBUS);
+	owner_watch = g_dbus_add_signal_watch(session, NULL, NULL,
+						DBUS_INTERFACE_DBUS,
+						"NameOwnerChanged",
+						name_owner_changed,
+						NULL, NULL);
 
-	dbus_bus_add_match(session, match, NULL);
 
-	snprintf(match, sizeof(match),
-			"interface=%s,member=PropertiesChanged,arg0=%s",
-			DBUS_INTERFACE_PROPERTIES,
-			"org.mpris.MediaPlayer2.Player");
-
-	list_names(session);
-
-	dbus_bus_add_match(session, match, NULL);
+	properties_watch = g_dbus_add_properties_watch(session, NULL, NULL,
+							MPRIS_PLAYER_INTERFACE,
+							properties_changed,
+							NULL, NULL);
 
 	memset(&sa, 0, sizeof(sa));
 	sa.sa_flags   = SA_NOCLDSTOP;
@@ -826,14 +818,25 @@ int main(int argc, char *argv[])
 	sigaction(SIGTERM, &sa, NULL);
 	sigaction(SIGINT,  &sa, NULL);
 
-	while (!__io_canceled && !__io_terminated) {
-		if (dbus_connection_read_write_dispatch(sys, 500) != TRUE)
-			break;
-		if (dbus_connection_read_write_dispatch(session, 500) != TRUE)
-			break;
-	}
+	client = g_dbus_client_new(sys, BLUEZ_BUS_NAME, BLUEZ_PATH);
 
+	g_dbus_client_set_connect_watch(client, connect_handler, NULL);
+	g_dbus_client_set_disconnect_watch(client, disconnect_handler, NULL);
+
+	g_dbus_client_set_proxy_handlers(client, proxy_added, proxy_removed,
+							NULL, NULL);
+
+	g_main_loop_run(main_loop);
+
+	g_dbus_remove_watch(session, owner_watch);
+	g_dbus_remove_watch(session, properties_watch);
+
+	g_dbus_client_unref(client);
+
+	dbus_connection_unref(session);
 	dbus_connection_unref(sys);
 
+	g_main_loop_unref(main_loop);
+
 	return 0;
 }
-- 
1.8.0.1


^ permalink raw reply related

* [PATCH BlueZ 12/13 v2] media: Implement new RegisterPlayer API
From: Luiz Augusto von Dentz @ 2013-01-10 13:37 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1357825038-21970-1-git-send-email-luiz.dentz@gmail.com>

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

RegisterPlayer now uses MPRIS spec
---
 profiles/audio/media.c | 294 ++++++++++++++++++++++++++++++++-----------------
 1 file changed, 195 insertions(+), 99 deletions(-)

diff --git a/profiles/audio/media.c b/profiles/audio/media.c
index b184f01..4b91656 100644
--- a/profiles/audio/media.c
+++ b/profiles/audio/media.c
@@ -28,6 +28,7 @@
 #endif
 
 #include <errno.h>
+#include <inttypes.h>
 
 #include <glib.h>
 #include <gdbus/gdbus.h>
@@ -51,7 +52,7 @@
 
 #define MEDIA_INTERFACE "org.bluez.Media1"
 #define MEDIA_ENDPOINT_INTERFACE "org.bluez.MediaEndpoint1"
-#define MEDIA_PLAYER_INTERFACE "org.bluez.MediaPlayer1"
+#define MEDIA_PLAYER_INTERFACE "org.mpris.MediaPlayer2.Player"
 
 #define REQUEST_TIMEOUT (3 * 1000)		/* 3 seconds */
 
@@ -1153,17 +1154,18 @@ static gboolean set_status(struct media_player *mp, DBusMessageIter *iter)
 
 static gboolean set_position(struct media_player *mp, DBusMessageIter *iter)
 {
-	uint32_t value;
+	uint64_t value;
 
-	if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_UINT32)
+	if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_INT64)
 			return FALSE;
 
 	dbus_message_iter_get_basic(iter, &value);
-	DBG("Position=%u", value);
 
-	mp->position = value;
+	mp->position = value / 1000;
 	g_timer_start(mp->timer);
 
+	DBG("Position=%u", mp->position);
+
 	if (!mp->position) {
 		avrcp_player_event(mp->player,
 					AVRCP_EVENT_TRACK_REACHED_START, NULL);
@@ -1181,12 +1183,98 @@ static gboolean set_position(struct media_player *mp, DBusMessageIter *iter)
 	return TRUE;
 }
 
+static void set_metadata(struct media_player *mp, const char *key,
+							const char *value)
+{
+	DBG("%s=%s", key, value);
+	g_hash_table_replace(mp->track, g_strdup(key), g_strdup(value));
+}
+
+static gboolean parse_string_metadata(struct media_player *mp, const char *key,
+							DBusMessageIter *iter)
+{
+	const char *value;
+
+	if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_STRING)
+		return FALSE;
+
+	dbus_message_iter_get_basic(iter, &value);
+
+	set_metadata(mp, key, value);
+
+	return TRUE;
+}
+
+static gboolean parse_array_metadata(struct media_player *mp, const char *key,
+							DBusMessageIter *iter)
+{
+	DBusMessageIter array;
+	const char *value;
+
+	if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY)
+		return FALSE;
+
+	dbus_message_iter_recurse(iter, &array);
+
+	if (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_INVALID)
+		return TRUE;
+
+	if (dbus_message_iter_get_arg_type(&array) != DBUS_TYPE_STRING)
+		return FALSE;
+
+	dbus_message_iter_get_basic(&array, &value);
+
+	set_metadata(mp, key, value);
+
+	return TRUE;
+}
+
+static gboolean parse_int64_metadata(struct media_player *mp, const char *key,
+							DBusMessageIter *iter)
+{
+	uint64_t value;
+	char valstr[20];
+
+	if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_INT64)
+		return FALSE;
+
+	dbus_message_iter_get_basic(iter, &value);
+
+	if (strcasecmp(key, "Duration") == 0) {
+		value /= 1000;
+		mp->duration = value;
+	}
+
+	snprintf(valstr, 20, "%" PRIu64, value);
+
+	set_metadata(mp, key, valstr);
+
+	return TRUE;
+}
+
+static gboolean parse_int32_metadata(struct media_player *mp, const char *key,
+							DBusMessageIter *iter)
+{
+	uint32_t value;
+	char valstr[20];
+
+	if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_INT32)
+		return FALSE;
+
+	dbus_message_iter_get_basic(iter, &value);
+
+	snprintf(valstr, 20, "%u", value);
+
+	set_metadata(mp, key, valstr);
+
+	return TRUE;
+}
+
 static gboolean parse_player_metadata(struct media_player *mp,
 							DBusMessageIter *iter)
 {
 	DBusMessageIter dict;
 	DBusMessageIter var;
-	GHashTable *track;
 	int ctype;
 	gboolean title = FALSE;
 	uint64_t uid;
@@ -1197,155 +1285,163 @@ static gboolean parse_player_metadata(struct media_player *mp,
 
 	dbus_message_iter_recurse(iter, &dict);
 
-	track = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
+	if (mp->track != NULL)
+		g_hash_table_unref(mp->track);
+
+	mp->track = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
 								g_free);
 
 	while ((ctype = dbus_message_iter_get_arg_type(&dict)) !=
 							DBUS_TYPE_INVALID) {
 		DBusMessageIter entry;
 		const char *key;
-		const char *string;
-		char valstr[20];
-		char *value;
-		uint32_t num;
-		int type;
 
 		if (ctype != DBUS_TYPE_DICT_ENTRY)
-			goto parse_error;
+			return FALSE;
 
 		dbus_message_iter_recurse(&dict, &entry);
 		if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_STRING)
-			goto parse_error;
+			return FALSE;
 
 		dbus_message_iter_get_basic(&entry, &key);
 		dbus_message_iter_next(&entry);
 
 		if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_VARIANT)
-			goto parse_error;
+			return FALSE;
 
 		dbus_message_iter_recurse(&entry, &var);
 
-		type = dbus_message_iter_get_arg_type(&var);
-
-		if (strcasecmp(key, "Title") == 0) {
-			if (type != DBUS_TYPE_STRING)
-				goto parse_error;
+		if (strcasecmp(key, "xesam:title") == 0) {
+			if (!parse_string_metadata(mp, "Title", &var))
+				return FALSE;
 			title = TRUE;
-			dbus_message_iter_get_basic(&var, &string);
-		} else if (strcasecmp(key, "Artist") == 0) {
-			if (type != DBUS_TYPE_STRING)
-				goto parse_error;
-
-			dbus_message_iter_get_basic(&var, &string);
-		} else if (strcasecmp(key, "Album") == 0) {
-			if (type != DBUS_TYPE_STRING)
-				goto parse_error;
-
-			dbus_message_iter_get_basic(&var, &string);
-		} else if (strcasecmp(key, "Genre") == 0) {
-			if (type != DBUS_TYPE_STRING)
-				goto parse_error;
-
-			dbus_message_iter_get_basic(&var, &string);
-		} else if (strcasecmp(key, "Duration") == 0) {
-			if (type != DBUS_TYPE_UINT32)
-				goto parse_error;
-
-			dbus_message_iter_get_basic(&var, &num);
-			mp->duration = num;
-		} else if (strcasecmp(key, "TrackNumber") == 0) {
-			if (type != DBUS_TYPE_UINT32)
-				goto parse_error;
-
-			dbus_message_iter_get_basic(&var, &num);
-		} else if (strcasecmp(key, "NumberOfTracks") == 0) {
-			if (type != DBUS_TYPE_UINT32)
-				goto parse_error;
-
-			dbus_message_iter_get_basic(&var, &num);
+		} else if (strcasecmp(key, "xesam:artist") == 0) {
+			if (!parse_array_metadata(mp, "Artist", &var))
+				return FALSE;
+		} else if (strcasecmp(key, "xesam:album") == 0) {
+			if (!parse_string_metadata(mp, "Album", &var))
+				return FALSE;
+		} else if (strcasecmp(key, "xesam:genre") == 0) {
+			if (!parse_array_metadata(mp, "Genre", &var))
+				return FALSE;
+		} else if (strcasecmp(key, "mpris:length") == 0) {
+			if (!parse_int64_metadata(mp, "Duration", &var))
+				return FALSE;
+		} else if (strcasecmp(key, "xesam:trackNumber") == 0) {
+			if (!parse_int32_metadata(mp, "TrackNumber", &var))
+				return FALSE;
 		} else
-			goto parse_error;
-
-		switch (type) {
-		case DBUS_TYPE_STRING:
-			value = g_strdup(string);
-			break;
-		default:
-			snprintf(valstr, 20, "%u", num);
-			value = g_strdup(valstr);
-		}
+			DBG("%s not supported, ignoring", key);
 
-		DBG("%s=%s", key, value);
-		g_hash_table_replace(track, g_strdup(key), value);
 		dbus_message_iter_next(&dict);
 	}
 
-	if (g_hash_table_size(track) == 0) {
-		g_hash_table_unref(track);
-		track = NULL;
-	} else if (title == FALSE)
-		g_hash_table_insert(track, g_strdup("Title"), g_strdup(""));
+	if (title == FALSE)
+		g_hash_table_insert(mp->track, g_strdup("Title"),
+								g_strdup(""));
 
-	if (mp->track != NULL)
-		g_hash_table_unref(mp->track);
-
-	mp->track = track;
 	mp->position = 0;
 	g_timer_start(mp->timer);
 	uid = get_uid(mp);
 
 	avrcp_player_event(mp->player, AVRCP_EVENT_TRACK_CHANGED, &uid);
-	avrcp_player_event(mp->player, AVRCP_EVENT_TRACK_REACHED_START,
-								NULL);
+	avrcp_player_event(mp->player, AVRCP_EVENT_TRACK_REACHED_START, NULL);
 
 	return TRUE;
+}
+
+static gboolean set_property(struct media_player *mp, const char *key,
+							const char *value)
+{
+	const char *curval;
+	GList *settings;
+
+	curval = g_hash_table_lookup(mp->settings, key);
+	if (g_strcmp0(curval, value) == 0)
+		return TRUE;
+
+	DBG("%s=%s", key, value);
+
+	g_hash_table_replace(mp->settings, g_strdup(key), g_strdup(value));
+
+	settings = list_settings(mp);
+
+	avrcp_player_event(mp->player, AVRCP_EVENT_SETTINGS_CHANGED, settings);
+
+	g_list_free(settings);
+
+	return TRUE;
+}
+
+static gboolean set_shuffle(struct media_player *mp, DBusMessageIter *iter)
+{
+	dbus_bool_t value;
+	const char *strvalue;
+
+	if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_BOOLEAN)
+		return FALSE;
+
+	dbus_message_iter_get_basic(iter, &value);
 
-parse_error:
-	if (track)
-		g_hash_table_unref(track);
+	strvalue = value ? "alltracks" : "off";
 
-	return FALSE;
+	return set_property(mp, "Shuffle", strvalue);
+}
+
+static const char *loop_status_to_repeat(const char *value)
+{
+	if (strcasecmp(value, "None") == 0)
+		return "off";
+	else if (strcasecmp(value, "Track") == 0)
+		return "singletrack";
+	else if (strcasecmp(value, "Track") == 0)
+		return "alltracks";
+
+	return NULL;
+}
+
+static gboolean set_repeat(struct media_player *mp, DBusMessageIter *iter)
+{
+	const char *value;
+
+	if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_STRING)
+		return FALSE;
+
+	dbus_message_iter_get_basic(iter, &value);
+
+	value = loop_status_to_repeat(value);
+	if (value == NULL)
+		return FALSE;
+
+	return set_property(mp, "Repeat", value);
 }
 
 static gboolean set_player_property(struct media_player *mp, const char *key,
 							DBusMessageIter *entry)
 {
 	DBusMessageIter var;
-	const char *value, *curval;
-	GList *settings;
 
 	if (dbus_message_iter_get_arg_type(entry) != DBUS_TYPE_VARIANT)
 		return FALSE;
 
 	dbus_message_iter_recurse(entry, &var);
 
-	if (strcasecmp(key, "Status") == 0)
+	if (strcasecmp(key, "PlaybackStatus") == 0)
 		return set_status(mp, &var);
 
 	if (strcasecmp(key, "Position") == 0)
 		return set_position(mp, &var);
 
-	if (strcasecmp(key, "Track") == 0)
+	if (strcasecmp(key, "Metadata") == 0)
 		return parse_player_metadata(mp, &var);
 
-	if (dbus_message_iter_get_arg_type(&var) != DBUS_TYPE_STRING)
-		return FALSE;
-
-	dbus_message_iter_get_basic(&var, &value);
-
-	curval = g_hash_table_lookup(mp->settings, key);
-	if (g_strcmp0(curval, value) == 0)
-		return TRUE;
-
-	DBG("%s=%s", key, value);
-
-	g_hash_table_replace(mp->settings, g_strdup(key), g_strdup(value));
-
-	settings = list_settings(mp);
+	if (strcasecmp(key, "Shuffle") == 0)
+		return set_shuffle(mp, &var);
 
-	avrcp_player_event(mp->player, AVRCP_EVENT_SETTINGS_CHANGED, settings);
+	if (strcasecmp(key, "LoopStatus") == 0)
+		return set_repeat(mp, &var);
 
-	g_list_free(settings);
+	DBG("%s not supported, ignoring", key);
 
 	return TRUE;
 }
-- 
1.8.0.1


^ permalink raw reply related

* [PATCH BlueZ 11/13 v2] test: Update test-player to register using MPRIS interface
From: Luiz Augusto von Dentz @ 2013-01-10 13:37 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1357825038-21970-1-git-send-email-luiz.dentz@gmail.com>

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

---
 test/simple-player | 35 +++++++++++++++++++++--------------
 1 file changed, 21 insertions(+), 14 deletions(-)

diff --git a/test/simple-player b/test/simple-player
index e331c52..01bec06 100755
--- a/test/simple-player
+++ b/test/simple-player
@@ -29,23 +29,30 @@ class Player(dbus.service.Object):
 				signal_name = "PropertiesChanged")
 		else:
 			track = dbus.Dictionary({
-					"Title" : "Title",
-					"Artist" : "Artist",
-					"Album" : "Album",
-					"Genre" : "Genre",
-					"NumberOfTracks" : dbus.UInt32(10),
-					"TrackNumber" : dbus.UInt32(1),
-					"Duration" : dbus.UInt32(10000) },
+					"xesam:title" : "Title",
+					"xesam:artist" : "Artist",
+					"xesam:album" : "Album",
+					"xesam:genre" : "Genre",
+					"xesam:trackNumber" : dbus.Int32(1),
+					"mpris:length" : dbus.Int64(10000) },
 					signature="sv")
 
 			self.properties = dbus.Dictionary({
-					"Equalizer" : "off",
-					"Repeat" : "off",
-					"Shuffle" : "off",
-					"Scan" : "off",
-					"Status" : "playing",
+					"PlaybackStatus" : "playing",
+					"LoopStatus" : "None",
+					"Rate" : dbus.Double(1.0),
+					"Shuffle" : dbus.Boolean(False),
+					"Metadata" : track,
+					"Volume" : dbus.Double(1.0),
 					"Position" : dbus.UInt32(0),
-					"Track" : track },
+					"MinimumRate" : dbus.Double(1.0),
+					"MaximumRate" : dbus.Double(1.0),
+					"CanGoNext" : dbus.Boolean(False),
+					"CanGoPrevious" : dbus.Boolean(False),
+					"CanPlay" : dbus.Boolean(False),
+					"CanSeek" : dbus.Boolean(False),
+					"CanControl" : dbus.Boolean(False),
+					},
 					signature="sv")
 
 			handler = InputHandler(self)
@@ -87,7 +94,7 @@ class InputHandler:
 			print('\t', cmd, self.commands[cmd], sep='')
 
 		print("\nUse python syntax to pass arguments to available methods.\n" \
-                "E.g.: PropertiesChanged({'Track' : {'Title': 'My title', \
+                "E.g.: PropertiesChanged({'Metadata' : {'Title': 'My title', \
 		'Album': 'my album' }})")
 		self.prompt()
 
-- 
1.8.0.1


^ permalink raw reply related

* [PATCH BlueZ 10/13 v2] media-api: Change RegisterPlayer to use MPRIS spec
From: Luiz Augusto von Dentz @ 2013-01-10 13:37 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1357825038-21970-1-git-send-email-luiz.dentz@gmail.com>

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

RegisterPlayer now expect registered paths to implement
org.mpris.MediaPlayer2.player interface accourding to MPRIS spec:

http://specifications.freedesktop.org/mpris-spec/latest/
---
 doc/media-api.txt | 70 ++++---------------------------------------------------
 1 file changed, 5 insertions(+), 65 deletions(-)

diff --git a/doc/media-api.txt b/doc/media-api.txt
index c9c2e7a..8c64520 100644
--- a/doc/media-api.txt
+++ b/doc/media-api.txt
@@ -45,78 +45,18 @@ Methods		void RegisterEndpoint(object endpoint, dict properties)
 
 			Unregister sender end point.
 
-		void RegisterPlayer(object player, dict properties,
-								dict metadata)
+		void RegisterPlayer(object player, dict properties)
 
 			Register a media player object to sender, the sender
 			can register as many objects as it likes.
 
+			Object must implement at least
+			org.mpris.MediaPlayer2.Player as defined in MPRIS 2.2
+			spec.
+
 			Note: If the sender disconnects its objects are
 			automatically unregistered.
 
-			Properties:
-
-				string Equalizer:
-
-					Possible values: "off" or "on"
-
-				string Repeat:
-
-					Possible values: "off", "singletrack",
-							"alltracks" or "group"
-
-				string Shuffle:
-
-					Possible values: "off", "alltracks" or
-							"group"
-
-				string Scan:
-
-					Possible values: "off", "alltracks" or
-							"group"
-
-				string Status:
-
-					Possible values: "playing", "stopped",
-							"paused",
-							"forward-seek",
-							"reverse-seek" or
-							"error"
-
-				uint32 Position
-
-					Playback position in milliseconds
-
-			Metadata:
-
-				string Title:
-
-					Track title name
-
-				string Artist:
-
-					Track artist name
-
-				string Album:
-
-					Track album name
-
-				string Genre:
-
-					Track genre name
-
-				uint32 NumberOfTracks:
-
-					Number of tracks in total
-
-				uint32 Number:
-
-					Track number
-
-				uint32 Duration:
-
-					Track duration in milliseconds
-
 			Possible Errors: org.bluez.Error.InvalidArguments
 					 org.bluez.Error.NotSupported
 
-- 
1.8.0.1


^ permalink raw reply related


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