Linux bluetooth development
 help / color / mirror / Atom feed
* [PATCHv2 06/10] android/avrcp: Add vendor unique passthrough request
From: Andrei Emeltchenko @ 2014-03-11 13:05 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1394543154-25355-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

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

---
 android/avctp.c     | 22 ++++++++++++++++++++++
 android/avctp.h     |  7 +++++++
 android/avrcp-lib.c |  5 +++++
 android/avrcp-lib.h |  2 ++
 4 files changed, 36 insertions(+)

diff --git a/android/avctp.c b/android/avctp.c
index d970250..33729f0 100644
--- a/android/avctp.c
+++ b/android/avctp.c
@@ -48,6 +48,7 @@
 #include "src/uinput.h"
 
 #include "avctp.h"
+#include "avrcp-lib.h"
 
 /* AV/C Panel 1.23, page 76:
  * command with the pressed value is valid for two seconds
@@ -1214,6 +1215,27 @@ static gboolean repeat_timeout(gpointer user_data)
 	return TRUE;
 }
 
+int avctp_passthrough_vendor_req(struct avctp *session, uint8_t op, bool press)
+{
+	uint8_t operands[7];
+
+	DBG("op %d press %d", op, press);
+
+	if (press)
+		operands[0] = AVC_VENDOR_UNIQUE;
+	else
+		operands[0] = AVC_VENDOR_UNIQUE | 0x80;
+
+	operands[1] = 5;
+	hton24(&operands[2], IEEEID_BTSIG);
+	bt_put_be16(op, &operands[5]);
+
+	return avctp_send_req(session, AVC_CTYPE_CONTROL,
+				AVC_SUBUNIT_PANEL, AVC_OP_PASSTHROUGH,
+				operands, sizeof(operands),
+				avctp_passthrough_rsp, NULL);
+}
+
 static void release_pressed(struct avctp *session)
 {
 	avctp_passthrough_release(session, session->key.op);
diff --git a/android/avctp.h b/android/avctp.h
index 2f419a2..4f65869 100644
--- a/android/avctp.h
+++ b/android/avctp.h
@@ -108,6 +108,11 @@
 #define AVC_BLUE			0x7c
 #define AVC_YELLOW			0x7c
 
+#define AVC_VENDOR_UNIQUE		0x7e
+
+#define AVC_VENDOR_NEXT_GROUP		0x00
+#define AVC_VENDOR_PREV_GROUP		0x01
+
 struct avctp;
 
 typedef bool (*avctp_passthrough_cb) (struct avctp *session,
@@ -170,3 +175,5 @@ int avctp_send_vendordep_req(struct avctp *session, uint8_t code,
 int avctp_send_browsing_req(struct avctp *session,
 				uint8_t *operands, size_t operand_count,
 				avctp_browsing_rsp_cb func, void *user_data);
+int avctp_passthrough_vendor_req(struct avctp *session, uint8_t op,
+								bool press);
diff --git a/android/avrcp-lib.c b/android/avrcp-lib.c
index 5400f80..a9bd438 100644
--- a/android/avrcp-lib.c
+++ b/android/avrcp-lib.c
@@ -471,3 +471,8 @@ int avrcp_register_notification_rsp(struct avrcp *session, uint8_t transaction,
 				AVC_SUBUNIT_PANEL, AVRCP_REGISTER_NOTIFICATION,
 				params, params_len);
 }
+
+int avrcp_passthrough_vendor_req(struct avrcp *session, uint8_t op, bool press)
+{
+	return avctp_passthrough_vendor_req(session->conn, op, press);
+}
diff --git a/android/avrcp-lib.h b/android/avrcp-lib.h
index 91a7d47..2acf0fb 100644
--- a/android/avrcp-lib.h
+++ b/android/avrcp-lib.h
@@ -164,3 +164,5 @@ 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_passthrough_vendor_req(struct avrcp *session, uint8_t op,
+								bool press);
-- 
1.8.3.2


^ permalink raw reply related

* [PATCHv2 05/10] unit/avrcp: Add /TP/INV/BI-01-C test
From: Andrei Emeltchenko @ 2014-03-11 13:05 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1394543154-25355-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

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

Test verifies that AVRCP_STATUS_INVALID_COMMAND returned when received
command with Invalid PDU ID.
---
 unit/test-avrcp.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/unit/test-avrcp.c b/unit/test-avrcp.c
index 09d7689..5d78a9a 100644
--- a/unit/test-avrcp.c
+++ b/unit/test-avrcp.c
@@ -1016,5 +1016,19 @@ int main(int argc, char *argv[])
 				AVRCP_REGISTER_NOTIFICATION,
 				0x00, 0x00, 0x01, AVRCP_STATUS_INVALID_PARAM));
 
+	/* Invalid commands */
+
+	/* Invalid PDU ID - TG */
+	define_test("/TP/INV/BI-01-C", test_server,
+			raw_pdu(0x00, 0x11, 0x0e, 0x03, 0x48, 0x00,
+				0x00, 0x19, 0x58,
+				/* Invalid PDU ID */
+				0xff,
+				0x00, 0x00, 0x00),
+			raw_pdu(0x02, 0x11, 0x0e, AVC_CTYPE_REJECTED,
+				0x48, 0x00, 0x00, 0x19, 0x58,
+				0xff, 0x00, 0x00, 0x01,
+				AVRCP_STATUS_INVALID_COMMAND));
+
 	return g_test_run();
 }
-- 
1.8.3.2


^ permalink raw reply related

* [PATCHv2 04/10] unit/avrcp: Add /TP/NFY/BI-01-C test
From: Andrei Emeltchenko @ 2014-03-11 13:05 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1394543154-25355-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

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

Test verifies that Target returns error on register for invalid event.
---
 unit/test-avrcp.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/unit/test-avrcp.c b/unit/test-avrcp.c
index 0e65789..09d7689 100644
--- a/unit/test-avrcp.c
+++ b/unit/test-avrcp.c
@@ -1003,5 +1003,18 @@ int main(int argc, char *argv[])
 				0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 				0x00, 0x00));
 
+	/* Register notification - Register for events invalid behavior - TG */
+	define_test("/TP/NFY/BI-01-C", test_server,
+			raw_pdu(0x00, 0x11, 0x0e, 0x03, 0x48, 0x00,
+				0x00, 0x19, 0x58, AVRCP_REGISTER_NOTIFICATION,
+				0x00, 0x00, 0x05,
+				/* Invalid event id */
+				0xff,
+				0x00, 0x00, 0x00, 0x00),
+			raw_pdu(0x02, 0x11, 0x0e, AVC_CTYPE_REJECTED,
+				0x48, 0x00, 0x00, 0x19, 0x58,
+				AVRCP_REGISTER_NOTIFICATION,
+				0x00, 0x00, 0x01, AVRCP_STATUS_INVALID_PARAM));
+
 	return g_test_run();
 }
-- 
1.8.3.2


^ permalink raw reply related

* [PATCHv2 03/10] unit/avrcp: Add /TP/NFY/BV-08-C test
From: Andrei Emeltchenko @ 2014-03-11 13:05 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1394543154-25355-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

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

Test verifies that Target issued Track Changed INTERIM response when
the track is SELECTED.
---
 unit/test-avrcp.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/unit/test-avrcp.c b/unit/test-avrcp.c
index fa93b25..0e65789 100644
--- a/unit/test-avrcp.c
+++ b/unit/test-avrcp.c
@@ -517,7 +517,9 @@ static ssize_t avrcp_handle_register_notification(struct avrcp *session,
 
 	switch (event) {
 	case AVRCP_EVENT_TRACK_CHANGED:
-		if (g_str_equal(context->data->test_name, "/TP/NFY/BV-05-C"))
+		if (g_str_equal(context->data->test_name, "/TP/NFY/BV-05-C") ||
+			g_str_equal(context->data->test_name,
+							"/TP/NFY/BV-08-C"))
 			memset(&pdu[1], 0, 8);
 		else
 			memset(&pdu[1], 0xff, 8);
@@ -989,5 +991,17 @@ int main(int argc, char *argv[])
 				0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 				0x00, 0x00));
 
+	/* Register notification - Track Changed - Selected Track - TG */
+	define_test("/TP/NFY/BV-08-C", test_server,
+			raw_pdu(0x00, 0x11, 0x0e, 0x03, 0x48, 0x00,
+				0x00, 0x19, 0x58, AVRCP_REGISTER_NOTIFICATION,
+				0x00, 0x00, 0x05, AVRCP_EVENT_TRACK_CHANGED,
+				0x00, 0x00, 0x00, 0x00),
+			raw_pdu(0x02, 0x11, 0x0e, AVC_CTYPE_INTERIM, 0x48, 0x00,
+				0x00, 0x19, 0x58, AVRCP_REGISTER_NOTIFICATION,
+				0x00, 0x00, 0x09, AVRCP_EVENT_TRACK_CHANGED,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00));
+
 	return g_test_run();
 }
-- 
1.8.3.2


^ permalink raw reply related

* [PATCHv2 02/10] unit/avrcp: Add /TP/NFY/BV-05-C test.
From: Andrei Emeltchenko @ 2014-03-11 13:05 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1394543154-25355-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

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

Test verifies Register notification - Track Changed - Track Playing.
---
 unit/test-avrcp.c | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/unit/test-avrcp.c b/unit/test-avrcp.c
index fe7009a..fa93b25 100644
--- a/unit/test-avrcp.c
+++ b/unit/test-avrcp.c
@@ -501,6 +501,7 @@ static ssize_t avrcp_handle_register_notification(struct avrcp *session,
 							uint8_t *params,
 							void *user_data)
 {
+	struct context *context = user_data;
 	uint8_t event;
 	uint8_t pdu[9];
 	size_t pdu_len;
@@ -516,7 +517,11 @@ static ssize_t avrcp_handle_register_notification(struct avrcp *session,
 
 	switch (event) {
 	case AVRCP_EVENT_TRACK_CHANGED:
-		memset(&pdu[1], 0xff, 8);
+		if (g_str_equal(context->data->test_name, "/TP/NFY/BV-05-C"))
+			memset(&pdu[1], 0, 8);
+		else
+			memset(&pdu[1], 0xff, 8);
+
 		pdu_len += 8;
 		break;
 	case AVRCP_EVENT_SETTINGS_CHANGED:
@@ -972,5 +977,17 @@ int main(int argc, char *argv[])
 				0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
 				0xff, 0xff));
 
+	/* Register notification - Track Changed - Track Playing - TG */
+	define_test("/TP/NFY/BV-05-C", test_server,
+			raw_pdu(0x00, 0x11, 0x0e, 0x03, 0x48, 0x00,
+				0x00, 0x19, 0x58, AVRCP_REGISTER_NOTIFICATION,
+				0x00, 0x00, 0x05, AVRCP_EVENT_TRACK_CHANGED,
+				0x00, 0x00, 0x00, 0x00),
+			raw_pdu(0x02, 0x11, 0x0e, AVC_CTYPE_INTERIM, 0x48, 0x00,
+				0x00, 0x19, 0x58, AVRCP_REGISTER_NOTIFICATION,
+				0x00, 0x00, 0x09, AVRCP_EVENT_TRACK_CHANGED,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00));
+
 	return g_test_run();
 }
-- 
1.8.3.2


^ permalink raw reply related

* [PATCHv2 01/10] unit/avrcp: Pass context to control handlers
From: Andrei Emeltchenko @ 2014-03-11 13:05 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1394458798-13822-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

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

---
 unit/test-avrcp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/unit/test-avrcp.c b/unit/test-avrcp.c
index 9760420..fe7009a 100644
--- a/unit/test-avrcp.c
+++ b/unit/test-avrcp.c
@@ -578,7 +578,7 @@ static void test_server(gconstpointer data)
 
 	avrcp_set_passthrough_handlers(context->session, passthrough_handlers,
 								context);
-	avrcp_set_control_handlers(context->session, control_handlers, NULL);
+	avrcp_set_control_handlers(context->session, control_handlers, context);
 
 	g_idle_add(send_pdu, context);
 
-- 
1.8.3.2


^ permalink raw reply related

* Re: [PATCH] android/handsfree: Fix list of HF features
From: Szymon Janc @ 2014-03-11 11:22 UTC (permalink / raw)
  To: Marcin Kraglak; +Cc: linux-bluetooth
In-Reply-To: <1394532999-15744-1-git-send-email-marcin.kraglak@tieto.com>

Hi Marcin,

On Tuesday 11 of March 2014 11:16:39 Marcin Kraglak wrote:
> Add missing Remote volume control feature
> ---
>  android/handsfree.c | 7 ++++---
>  1 file changed, 4 insertions(+), 3 deletions(-)
> 
> diff --git a/android/handsfree.c b/android/handsfree.c
> index 0828de8..4f999e1 100644
> --- a/android/handsfree.c
> +++ b/android/handsfree.c
> @@ -64,9 +64,10 @@
>  #define HFP_HF_FEAT_3WAY	0x00000002
>  #define HFP_HF_FEAT_CLI		0x00000004
>  #define HFP_HF_FEAT_VR		0x00000008
> -#define HFP_HF_FEAT_ECS		0x00000010
> -#define HFP_HF_FEAT_ECC		0x00000020
> -#define HFP_HF_FEAT_CODEC	0x00000040
> +#define HFP_HF_FEAT_RVC		0x00000010
> +#define HFP_HF_FEAT_ECS		0x00000020
> +#define HFP_HF_FEAT_ECC		0x00000040
> +#define HFP_HF_FEAT_CODEC	0x00000080
>  
>  #define HFP_AG_FEATURES ( HFP_AG_FEAT_3WAY | HFP_AG_FEAT_ECNR |\
>  			HFP_AG_FEAT_VR | HFP_AG_FEAT_REJ_CALL |\
> 

Applied, thanks.

-- 
Best regards, 
Szymon Janc

^ permalink raw reply

* [PATCH] android/handsfree: Fix list of HF features
From: Marcin Kraglak @ 2014-03-11 10:16 UTC (permalink / raw)
  To: linux-bluetooth

Add missing Remote volume control feature
---
 android/handsfree.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/android/handsfree.c b/android/handsfree.c
index 0828de8..4f999e1 100644
--- a/android/handsfree.c
+++ b/android/handsfree.c
@@ -64,9 +64,10 @@
 #define HFP_HF_FEAT_3WAY	0x00000002
 #define HFP_HF_FEAT_CLI		0x00000004
 #define HFP_HF_FEAT_VR		0x00000008
-#define HFP_HF_FEAT_ECS		0x00000010
-#define HFP_HF_FEAT_ECC		0x00000020
-#define HFP_HF_FEAT_CODEC	0x00000040
+#define HFP_HF_FEAT_RVC		0x00000010
+#define HFP_HF_FEAT_ECS		0x00000020
+#define HFP_HF_FEAT_ECC		0x00000040
+#define HFP_HF_FEAT_CODEC	0x00000080
 
 #define HFP_AG_FEATURES ( HFP_AG_FEAT_3WAY | HFP_AG_FEAT_ECNR |\
 			HFP_AG_FEAT_VR | HFP_AG_FEAT_REJ_CALL |\
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH 3/3] android: Enable LE if controller supports it
From: Grzegorz Kolodziejczyk @ 2014-03-11 10:09 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1394532573-19278-1-git-send-email-grzegorz.kolodziejczyk@tieto.com>

---
 android/bluetooth.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/android/bluetooth.c b/android/bluetooth.c
index ba4f14b..2732390 100644
--- a/android/bluetooth.c
+++ b/android/bluetooth.c
@@ -2015,6 +2015,9 @@ static void read_info_complete(uint8_t status, uint16_t length,
 	if (missing_settings & MGMT_SETTING_PAIRABLE)
 		set_mode(MGMT_OP_SET_PAIRABLE, 0x01);
 
+	if (missing_settings & MGMT_SETTING_LE)
+		set_mode(MGMT_OP_SET_LE, 0x01);
+
 	return;
 
 failed:
-- 
1.8.5.2


^ permalink raw reply related

* [PATCH 2/3] emulator/btdev: Add support for LE set scan response command
From: Grzegorz Kolodziejczyk @ 2014-03-11 10:09 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1394532573-19278-1-git-send-email-grzegorz.kolodziejczyk@tieto.com>

This adds support for btdev LE set scan response command.
---
 emulator/btdev.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/emulator/btdev.c b/emulator/btdev.c
index b54f91e..a5a9123 100644
--- a/emulator/btdev.c
+++ b/emulator/btdev.c
@@ -2454,6 +2454,13 @@ static void default_cmd(struct btdev *btdev, uint16_t opcode,
 		cmd_complete(btdev, opcode, &lte, sizeof(lte));
 		break;
 
+	case BT_HCI_CMD_LE_SET_SCAN_RSP_DATA:
+		if (btdev->type == BTDEV_TYPE_BREDR)
+			goto unsupported;
+		status = BT_HCI_ERR_SUCCESS;
+		cmd_complete(btdev, opcode, &status, sizeof(status));
+		break;
+
 	default:
 		goto unsupported;
 	}
-- 
1.8.5.2


^ permalink raw reply related

* [PATCH 1/3] android/tester: Change hciemu type to bredr
From: Grzegorz Kolodziejczyk @ 2014-03-11 10:09 UTC (permalink / raw)
  To: linux-bluetooth

Current test cases works on bredrle hciemu types. Now test cases
don't require to support LE mode. Btdev support for LE devices have
to be enhanced to behave correctly with mode set to LE. After enhancing
support in bthost, hciemu type can be retyped to bredrle.
---
 android/android-tester.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/android/android-tester.c b/android/android-tester.c
index b762a2d..49a636f 100644
--- a/android/android-tester.c
+++ b/android/android-tester.c
@@ -4422,13 +4422,18 @@ static void test_hidhost_get_report(const void *test_data)
 		tester_test_failed();
 }
 
+/* Changing hciemu type to bredr is a teporary fix while bthost don't handle
+ * all LE commands. A lot of test cases - especially those which uses scan
+ * (remote device tests) will fail. After enahancing bthost hciemu type can be
+ * rechanged to BREDRLE.
+ */
 #define test_bredrle(name, data, test_setup, test, test_teardown) \
 	do { \
 		struct test_data *user; \
 		user = g_malloc0(sizeof(struct test_data)); \
 		if (!user) \
 			break; \
-		user->hciemu_type = HCIEMU_TYPE_BREDRLE; \
+		user->hciemu_type = HCIEMU_TYPE_BREDR; \
 		user->test_data = data; \
 		tester_add_full(name, data, test_pre_setup, test_setup, \
 				test, test_teardown, test_post_teardown, \
-- 
1.8.5.2


^ permalink raw reply related

* Re: Passive scanning of iBeacons results in a "Data Buffer Overflow"
From: Terry Hardie @ 2014-03-11  0:54 UTC (permalink / raw)
  To: Anderson Lizardo; +Cc: BlueZ development
In-Reply-To: <CAJdJm_M=qHZFdGRd0B3DTNCJXyraj4+P4aDG6t7y_w76XCXYdA@mail.gmail.com>

On 2014-03-10 06:21, Anderson Lizardo wrote:
> Hi Terry,
> 
> On Sat, Mar 8, 2014 at 3:19 AM, Terry Hardie <terryh@orcas.net> wrote:
>> The problem is when running a lescan (hcitool lescan) with a LE device 
>> in
>> paring mode, which is transmitting a lot of LE Advertising report 
>> packets,
>> the HCI drivers eventually loses sync. I've traced it down to a 
>> duplicate
>> USB fragment.
> 
> I think your logs show missing USB packets (not duplicated)... More
> details below.

Interesting that it always loses 2 packets, and never 1, that's why I 
assumed duplication...

> In summary, it is expected that for devices that don't change address,
> the only byte to change is the RSSI (last byte of the last fragment).
> That's why the 2 first fragments are usually the same for all
> advertising packets.

You asked in another email if I tried a powered hub. Yes, I tried a 
powered hub. I get the same results.

Also, although it's not common, I also see these lost frames outside of 
a scan. A scan is just the easiest way to reproduce it. If I leave a tag 
broadcasting once per second, 2 receivers on the same USB bus, after an 
hour or so, the same problem happens (and this is only 1 broadcast per 
second from the PROX tag, received by 2 receivers simultaneously, 
resulting in each receiver sending 3 USB transfers to the host - 6 USB 
transfer total), so this is not just limited to high packet rates. I 
think there's some problem with USB bus contention, especially since 
both receivers try to send data to the host at EXACTLY the same time.

Terry

^ permalink raw reply

* [PATCH 7/7] doc: Update test-hfp coverage statistics
From: Szymon Janc @ 2014-03-10 23:10 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1394493034-2417-1-git-send-email-szymon.janc@gmail.com>

---
 doc/test-coverage.txt | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/doc/test-coverage.txt b/doc/test-coverage.txt
index b00ba1d..f6f2de0 100644
--- a/doc/test-coverage.txt
+++ b/doc/test-coverage.txt
@@ -16,7 +16,7 @@ test-mgmt		   2	Management interface handling
 test-textfile		   4	Old textfile storage format
 test-ringbuf		   3	Ring buffer functionality
 test-queue		   1	Queue handling functionality
-test-hfp		   9	HFP Audio Gateway functionality
+test-hfp		  13	HFP Audio Gateway functionality
 test-avdtp		  60	AVDTP qualification test cases
 test-avctp		   9	AVCTP qualification test cases
 test-avrcp		  37	AVRCP qualification test cases
@@ -27,7 +27,7 @@ test-gobex-apparam	  18	OBEX apparam handling
 test-gobex-transfer	  36	OBEX transfer handling
 test-gdbus-client	  12	D-Bus client handling
 			-----
-			 442
+			 446
 
 
 Automated end-to-end testing
-- 
1.9.0


^ permalink raw reply related

* [PATCH 6/7] shared/hfp: Don't update offset if string parsing failed
From: Szymon Janc @ 2014-03-10 23:10 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1394493034-2417-1-git-send-email-szymon.janc@gmail.com>

---
 src/shared/hfp.c | 29 +++++++++++++++++++----------
 1 file changed, 19 insertions(+), 10 deletions(-)

diff --git a/src/shared/hfp.c b/src/shared/hfp.c
index 3256931..36c8c3e 100644
--- a/src/shared/hfp.c
+++ b/src/shared/hfp.c
@@ -299,20 +299,22 @@ bool hfp_gw_result_get_string(struct hfp_gw_result *result, char *buf,
 {
 	int i = 0;
 	const char *data = result->data;
+	unsigned int offset;
 
 	skip_whitespace(result);
 
 	if (data[result->offset] != '"')
 		return false;
 
-	result->offset++;
+	offset = result->offset;
+	offset++;
 
-	while (data[result->offset] != '\0' && data[result->offset] != '"') {
+	while (data[offset] != '\0' && data[offset] != '"') {
 		if (i == len)
 			return false;
 
-		buf[i++] = data[result->offset];
-		result->offset++;
+		buf[i++] = data[offset];
+		offset++;
 	}
 
 	if (i == len)
@@ -320,11 +322,13 @@ bool hfp_gw_result_get_string(struct hfp_gw_result *result, char *buf,
 
 	buf[i] = '\0';
 
-	if (data[result->offset] == '"')
-		result->offset++;
+	if (data[offset] == '"')
+		offset++;
 	else
 		return false;
 
+	result->offset = offset;
+
 	skip_whitespace(result);
 	next_field(result);
 
@@ -335,6 +339,7 @@ bool hfp_gw_result_get_unquoted_string(struct hfp_gw_result *result, char *buf,
 								uint8_t len)
 {
 	const char *data = result->data;
+	unsigned int offset;
 	int i = 0;
 	char c;
 
@@ -344,13 +349,15 @@ bool hfp_gw_result_get_unquoted_string(struct hfp_gw_result *result, char *buf,
 	if (c == '"' || c == ')' || c == '(')
 		return false;
 
-	while (data[result->offset] != '\0' && data[result->offset] != ','
-					&& data[result->offset] != ')') {
+	offset = result->offset;
+
+	while (data[offset] != '\0' && data[offset] != ',' &&
+							data[offset] != ')') {
 		if (i == len)
 			return false;
 
-		buf[i++] = data[result->offset];
-		result->offset++;
+		buf[i++] = data[offset];
+		offset++;
 	}
 
 	if (i == len)
@@ -358,6 +365,8 @@ bool hfp_gw_result_get_unquoted_string(struct hfp_gw_result *result, char *buf,
 
 	buf[i] = '\0';
 
+	result->offset = offset;
+
 	next_field(result);
 
 	return true;
-- 
1.9.0


^ permalink raw reply related

* [PATCH 5/7] shared/hfp: Use unsigned int for offset
From: Szymon Janc @ 2014-03-10 23:10 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1394493034-2417-1-git-send-email-szymon.janc@gmail.com>

---
 src/shared/hfp.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/shared/hfp.c b/src/shared/hfp.c
index e481360..3256931 100644
--- a/src/shared/hfp.c
+++ b/src/shared/hfp.c
@@ -72,7 +72,7 @@ struct cmd_handler {
 
 struct hfp_gw_result {
 	const char *data;
-	int offset;
+	unsigned int offset;
 };
 
 static void destroy_cmd_handler(void *data)
@@ -245,8 +245,8 @@ bool hfp_gw_result_get_number_default(struct hfp_gw_result *result,
 
 bool hfp_gw_result_get_number(struct hfp_gw_result *result, unsigned int *val)
 {
+	unsigned int i;
 	int tmp = 0;
-	int i;
 
 	skip_whitespace(result);
 
-- 
1.9.0


^ permalink raw reply related

* [PATCH 4/7] shared/hfp: Fix not NULL terminating parsed strings
From: Szymon Janc @ 2014-03-10 23:10 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1394493034-2417-1-git-send-email-szymon.janc@gmail.com>

If there were not enough space in output buffer
hfp_gw_result_get_string() and hfp_gw_result_get_unquoted_string()
wcould return true, but resulting string would not be NULL terminated.
---
 src/shared/hfp.c | 24 ++++++++++++++++--------
 1 file changed, 16 insertions(+), 8 deletions(-)

diff --git a/src/shared/hfp.c b/src/shared/hfp.c
index 1be53fb..e481360 100644
--- a/src/shared/hfp.c
+++ b/src/shared/hfp.c
@@ -308,13 +308,17 @@ bool hfp_gw_result_get_string(struct hfp_gw_result *result, char *buf,
 	result->offset++;
 
 	while (data[result->offset] != '\0' && data[result->offset] != '"') {
-		if (i < len)
-			buf[i++] = data[result->offset];
+		if (i == len)
+			return false;
+
+		buf[i++] = data[result->offset];
 		result->offset++;
 	}
 
-	if (i < len)
-		buf[i++] = '\0';
+	if (i == len)
+		return false;
+
+	buf[i] = '\0';
 
 	if (data[result->offset] == '"')
 		result->offset++;
@@ -342,13 +346,17 @@ bool hfp_gw_result_get_unquoted_string(struct hfp_gw_result *result, char *buf,
 
 	while (data[result->offset] != '\0' && data[result->offset] != ','
 					&& data[result->offset] != ')') {
-		if (i < len)
-			buf[i++] = data[result->offset];
+		if (i == len)
+			return false;
+
+		buf[i++] = data[result->offset];
 		result->offset++;
 	}
 
-	if (i < len)
-		buf[i++] = '\0';
+	if (i == len)
+		return false;
+
+	buf[i] = '\0';
 
 	next_field(result);
 
-- 
1.9.0


^ permalink raw reply related

* [PATCH 3/7] unit/test-hfp: Add initial tests for getting quoted string
From: Szymon Janc @ 2014-03-10 23:10 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1394493034-2417-1-git-send-email-szymon.janc@gmail.com>

---
 unit/test-hfp.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 60 insertions(+)

diff --git a/unit/test-hfp.c b/unit/test-hfp.c
index 7837fc3..445fcb7 100644
--- a/unit/test-hfp.c
+++ b/unit/test-hfp.c
@@ -349,6 +349,54 @@ static void check_ustring_2(struct hfp_gw_result *result,
 	hfp_gw_send_result(context->hfp, HFP_RESULT_ERROR);
 }
 
+static void check_string_1(struct hfp_gw_result *result,
+				enum hfp_gw_cmd_type type, void *user_data)
+{
+	struct context *context = user_data;
+	const struct test_pdu *pdu;
+	unsigned int i = 4, j = 0;
+	char str[10];
+
+	pdu = &context->data->pdu_list[context->pdu_offset++];
+
+	g_assert(type == pdu->type);
+
+	g_assert(hfp_gw_result_get_string(result, str, sizeof(str)));
+
+	while (context->data->pdu_list[1].data[i] != '\"') {
+		g_assert(j < sizeof(str));
+		g_assert(str[j] == context->data->pdu_list[1].data[i]);
+
+		i++;
+		j++;
+	}
+
+	g_assert(context->data->pdu_list[1].data[i] == '\"');
+	g_assert(str[j] == '\0');
+
+	hfp_gw_send_result(context->hfp, HFP_RESULT_ERROR);
+}
+
+static void check_string_2(struct hfp_gw_result *result,
+				enum hfp_gw_cmd_type type, void *user_data)
+{
+	struct context *context = user_data;
+	const struct test_pdu *pdu;
+	char str[10];
+
+	memset(str, 'X', sizeof(str));
+
+	pdu = &context->data->pdu_list[context->pdu_offset++];
+
+	g_assert(type == pdu->type);
+
+	g_assert(!hfp_gw_result_get_string(result, str, 3));
+
+	g_assert(str[3] == 'X');
+
+	hfp_gw_send_result(context->hfp, HFP_RESULT_ERROR);
+}
+
 int main(int argc, char *argv[])
 {
 	g_test_init(&argc, &argv, NULL);
@@ -402,6 +450,18 @@ int main(int argc, char *argv[])
 			raw_pdu('A', 'T', 'D', '0', '1', '2', '3', '\r'),
 			type_pdu(HFP_GW_CMD_TYPE_SET, 0),
 			data_end());
+	define_test("/hfp/test_string_1", test_register, check_string_1,
+			raw_pdu('D', '\0'),
+			raw_pdu('A', 'T', 'D', '\"', '0', '1', '2', '3', '\"',
+									'\r'),
+			type_pdu(HFP_GW_CMD_TYPE_SET, 0),
+			data_end());
+	define_test("/hfp/test_string_2", test_register, check_string_2,
+			raw_pdu('D', '\0'),
+			raw_pdu('A', 'T', 'D', '\"', '0', '1', '2', '3', '\"',
+									'\r'),
+			type_pdu(HFP_GW_CMD_TYPE_SET, 0),
+			data_end());
 
 	return g_test_run();
 }
-- 
1.9.0


^ permalink raw reply related

* [PATCH 2/7] unit/test-hfp: Add initial tests for getting unquoted string
From: Szymon Janc @ 2014-03-10 23:10 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1394493034-2417-1-git-send-email-szymon.janc@gmail.com>

---
 unit/test-hfp.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 57 insertions(+)

diff --git a/unit/test-hfp.c b/unit/test-hfp.c
index adc600b..7837fc3 100644
--- a/unit/test-hfp.c
+++ b/unit/test-hfp.c
@@ -302,6 +302,53 @@ static void test_fragmented(gconstpointer data)
 	execute_context(context);
 }
 
+static void check_ustring_1(struct hfp_gw_result *result,
+				enum hfp_gw_cmd_type type, void *user_data)
+{
+	struct context *context = user_data;
+	const struct test_pdu *pdu;
+	unsigned int i = 3, j = 0;
+	char str[10];
+
+	pdu = &context->data->pdu_list[context->pdu_offset++];
+
+	g_assert(type == pdu->type);
+
+	g_assert(hfp_gw_result_get_unquoted_string(result, str, sizeof(str)));
+
+	while (context->data->pdu_list[1].data[i] != '\r') {
+		g_assert(j < sizeof(str));
+		g_assert(str[j] == context->data->pdu_list[1].data[i]);
+
+		i++;
+		j++;
+	}
+
+	g_assert(str[j] == '\0');
+
+	hfp_gw_send_result(context->hfp, HFP_RESULT_ERROR);
+}
+
+static void check_ustring_2(struct hfp_gw_result *result,
+				enum hfp_gw_cmd_type type, void *user_data)
+{
+	struct context *context = user_data;
+	const struct test_pdu *pdu;
+	char str[10];
+
+	memset(str, 'X', sizeof(str));
+
+	pdu = &context->data->pdu_list[context->pdu_offset++];
+
+	g_assert(type == pdu->type);
+
+	g_assert(!hfp_gw_result_get_unquoted_string(result, str, 3));
+
+	g_assert(str[3] == 'X');
+
+	hfp_gw_send_result(context->hfp, HFP_RESULT_ERROR);
+}
+
 int main(int argc, char *argv[])
 {
 	g_test_init(&argc, &argv, NULL);
@@ -345,6 +392,16 @@ int main(int argc, char *argv[])
 			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());
+	define_test("/hfp/test_ustring_1", test_register, check_ustring_1,
+			raw_pdu('D', '\0'),
+			raw_pdu('A', 'T', 'D', '0', '1', '2', '3', '\r'),
+			type_pdu(HFP_GW_CMD_TYPE_SET, 0),
+			data_end());
+	define_test("/hfp/test_ustring_2", test_register, check_ustring_2,
+			raw_pdu('D', '\0'),
+			raw_pdu('A', 'T', 'D', '0', '1', '2', '3', '\r'),
+			type_pdu(HFP_GW_CMD_TYPE_SET, 0),
+			data_end());
 
 	return g_test_run();
 }
-- 
1.9.0


^ permalink raw reply related

* [PATCH 1/7] unit/test-hfp: Add ability to pass custom result handler to test
From: Szymon Janc @ 2014-03-10 23:10 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

---
 unit/test-hfp.c | 30 +++++++++++++++++-------------
 1 file changed, 17 insertions(+), 13 deletions(-)

diff --git a/unit/test-hfp.c b/unit/test-hfp.c
index 5218a2b..adc600b 100644
--- a/unit/test-hfp.c
+++ b/unit/test-hfp.c
@@ -51,6 +51,7 @@ struct test_pdu {
 struct test_data {
 	char *test_name;
 	struct test_pdu *pdu_list;
+	hfp_result_func_t result_func;
 };
 
 #define data(args...) ((const unsigned char[]) { args })
@@ -83,7 +84,7 @@ struct test_data {
 		.fragmented = true,				\
 	}
 
-#define define_test(name, function, args...)				\
+#define define_test(name, function, result_function, args...)		\
 	do {								\
 		const struct test_pdu pdus[] = {			\
 			args, { }					\
@@ -91,6 +92,7 @@ struct test_data {
 		static struct test_data data;				\
 		data.test_name = g_strdup(name);			\
 		data.pdu_list = g_malloc(sizeof(pdus));			\
+		data.result_func = result_function;			\
 		memcpy(data.pdu_list, pdus, sizeof(pdus));		\
 		g_test_add_data_func(name, &data, function);		\
 	} while (0)
@@ -252,9 +254,11 @@ static void test_register(gconstpointer data)
 	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);
+	if (context->data->result_func) {
+		ret = hfp_gw_register(context->hfp, context->data->result_func,
+					(char *)pdu->data, context, NULL);
+		g_assert(ret);
+	}
 
 	pdu = &context->data->pdu_list[context->pdu_offset++];
 
@@ -302,42 +306,42 @@ 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,
+	define_test("/hfp/test_init", test_init, NULL, data_end());
+	define_test("/hfp/test_cmd_handler_1", test_command_handler, NULL,
 			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,
+	define_test("/hfp/test_cmd_handler_2", test_command_handler, NULL,
 			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,
+	define_test("/hfp/test_register_1", test_register, prefix_handler,
 			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());
-	define_test("/hfp/test_register_2", test_register,
+	define_test("/hfp/test_register_2", test_register, prefix_handler,
 			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());
-	define_test("/hfp/test_register_3", test_register,
+	define_test("/hfp/test_register_3", test_register, prefix_handler,
 			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());
-	define_test("/hfp/test_register_4", test_register,
+	define_test("/hfp/test_register_4", test_register, prefix_handler,
 			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());
-	define_test("/hfp/test_register_5", test_register,
+	define_test("/hfp/test_register_5", test_register, prefix_handler,
 			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());
-	define_test("/hfp/test_fragmented_1", test_fragmented,
+	define_test("/hfp/test_fragmented_1", test_fragmented, NULL,
 			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());
-- 
1.9.0


^ permalink raw reply related

* [PATCH] Bluetooth: Enable duplicates filter in background scan
From: Andre Guedes @ 2014-03-10 21:26 UTC (permalink / raw)
  To: linux-bluetooth

To avoid flooding the host with useless advertising reports during
background scan, we enable the duplicates filter from controller.

However, enabling duplicates filter requires a small change in
background scan routine in order to fix the following scenario:
  1) Background scan is running.
  2) A device disconnects and starts advertising.
  3) Before host gets the disconnect event, the advertising is reported
     to host. Since there is no pending LE connection at that time,
     nothing happens.
  4) Host gets the disconnection event and adds a pending connection.
  5) No advertising is reported (since controller is filtering) and the
     connection is never established.

So, to address this scenario, we should always restart background scan
to unsure we don't miss any advertising report (due to duplicates
filter).

Signed-off-by: Andre Guedes <andre.guedes@openbossa.org>
---
 net/bluetooth/hci_core.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 8bbfdea..a27d0b8 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -5270,7 +5270,7 @@ void hci_req_add_le_passive_scan(struct hci_request *req)
 
 	memset(&enable_cp, 0, sizeof(enable_cp));
 	enable_cp.enable = LE_SCAN_ENABLE;
-	enable_cp.filter_dup = LE_SCAN_FILTER_DUP_DISABLE;
+	enable_cp.filter_dup = LE_SCAN_FILTER_DUP_ENABLE;
 	hci_req_add(req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(enable_cp),
 		    &enable_cp);
 }
@@ -5313,10 +5313,6 @@ void hci_update_background_scan(struct hci_dev *hdev)
 		 * keep the background scan running.
 		 */
 
-		/* If controller is already scanning we are done. */
-		if (test_bit(HCI_LE_SCAN, &hdev->dev_flags))
-			return;
-
 		/* If controller is connecting, we should not start scanning
 		 * since some controllers are not able to scan and connect at
 		 * the same time.
@@ -5325,6 +5321,12 @@ void hci_update_background_scan(struct hci_dev *hdev)
 		if (conn)
 			return;
 
+		/* If controller is currently scanning, we stop it to ensure we
+		 * don't miss any advertising (due to duplicates filter).
+		 */
+		if (test_bit(HCI_LE_SCAN, &hdev->dev_flags))
+			hci_req_add_le_scan_disable(&req);
+
 		hci_req_add_le_passive_scan(&req);
 
 		BT_DBG("%s starting background scanning", hdev->name);
-- 
1.8.5.4


^ permalink raw reply related

* Re: [PATCH] bdaddr: Remove *_CP_SIZE defines
From: Johan Hedberg @ 2014-03-10 20:30 UTC (permalink / raw)
  To: Petri Gynther; +Cc: linux-bluetooth
In-Reply-To: <20140307225545.E2760100887@puck.mtv.corp.google.com>

Hi Petri,

On Fri, Mar 07, 2014, Petri Gynther wrote:
> Remove *_CP_SIZE defines and use sizeof(cp) instead.
> ---
>  tools/bdaddr.c | 15 +++++----------
>  1 file changed, 5 insertions(+), 10 deletions(-)

Applied. Thanks.

Johan

^ permalink raw reply

* Re: [PATCH] bdaddr: Add Marvell support
From: Johan Hedberg @ 2014-03-10 20:30 UTC (permalink / raw)
  To: Petri Gynther; +Cc: linux-bluetooth
In-Reply-To: <20140307222807.97CEA100887@puck.mtv.corp.google.com>

Hi Petri,

On Fri, Mar 07, 2014, Petri Gynther wrote:
> ---
>  tools/bdaddr.c | 26 ++++++++++++++++++++++++++
>  1 file changed, 26 insertions(+)

Applied. Thanks.

Johan

^ permalink raw reply

* Re: [PATCH v2] Bluetooth: Make LTK and CSRK only persisent when bonding
From: Johan Hedberg @ 2014-03-10 20:02 UTC (permalink / raw)
  To: Marcel Holtmann; +Cc: linux-bluetooth
In-Reply-To: <1394433522-8561-1-git-send-email-marcel@holtmann.org>

Hi Marcel,

On Sun, Mar 09, 2014, Marcel Holtmann wrote:
> In case the pairable option has been disabled, the pairing procedure
> does not create keys for bonding. This means that these generated keys
> should not be stored persistently.
> 
> For LTK and CSRK this is important to tell userspace to not store these
> new keys. They will be available for the lifetime of the device, but
> after the next power cycle they should not be used anymore.
> 
> Make sure that the SMP pairing procedures rememberes the authentication
> request information for bonding and if both sides request bonding, then
> inform userspace to actually store the keys persistently.
> 
> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
> ---
>  include/net/bluetooth/hci_core.h |  5 +++--
>  net/bluetooth/mgmt.c             |  9 +++++----
>  net/bluetooth/smp.c              | 13 +++++++++----
>  net/bluetooth/smp.h              |  1 +
>  4 files changed, 18 insertions(+), 10 deletions(-)

Thanks for the patch. I've applied a slightly modified version which
relies on the existing smp->preq/prsp variables as discussed on IRC.

Johan

^ permalink raw reply

* [PATCH BlueZ v0 16/16] tools: Emit property changed when Value changes
From: Claudio Takahasi @ 2014-03-10 18:50 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: claudio.takahasi
In-Reply-To: <1394477445-8987-1-git-send-email-claudio.takahasi@openbossa.org>

This patch extends gatt-service tool, emitting PropertiesChanged for
"Value" when a new value is set. This flow represents the handling of
ATT Write Command or Write Request which is translated to a GDBusProxy
set property. PropertiesChanged will be tracked by the characteristic
GDBusProxy in order to detect "Value" changes.
---
 tools/gatt-service.c | 33 ++++++++++++++++++---------------
 1 file changed, 18 insertions(+), 15 deletions(-)

diff --git a/tools/gatt-service.c b/tools/gatt-service.c
index 481495c..5878dc3 100644
--- a/tools/gatt-service.c
+++ b/tools/gatt-service.c
@@ -47,9 +47,11 @@
 
 static GMainLoop *main_loop;
 static GSList *services;
+static DBusConnection *connection;
 
 struct characteristic {
 	char *uuid;
+	char *path;
 	uint8_t *value;
 	int vlen;
 };
@@ -110,6 +112,8 @@ static void chr_set_value(const GDBusPropertyTable *property,
 	chr->vlen = len;
 
 	g_dbus_pending_property_success(id);
+	g_dbus_emit_property_changed(connection, chr->path,
+						GATT_CHR_IFACE, "Value");
 }
 
 static const GDBusPropertyTable chr_properties[] = {
@@ -163,6 +167,7 @@ static void chr_iface_destroy(gpointer user_data)
 
 	g_free(chr->uuid);
 	g_free(chr->value);
+	g_free(chr->path);
 	g_free(chr);
 }
 
@@ -183,6 +188,7 @@ static int register_characteristic(DBusConnection *conn, const char *uuid,
 
 	chr->value = g_memdup(value, vlen);
 	chr->vlen = vlen;
+	chr->path = path;
 
 	if (g_dbus_register_interface(conn, path, GATT_CHR_IFACE,
 					NULL, NULL, chr_properties,
@@ -191,18 +197,16 @@ static int register_characteristic(DBusConnection *conn, const char *uuid,
 		ret = -EIO;
 	}
 
-	g_free(path);
-
 	return ret;
 }
 
-static char *register_service(DBusConnection *conn, const char *uuid)
+static char *register_service(const char *uuid)
 {
 	static int id = 1;
 	char *path;
 
 	path = g_strdup_printf("/service%d", id++);
-	if (g_dbus_register_interface(conn, path, GATT_SERVICE_IFACE,
+	if (g_dbus_register_interface(connection, path, GATT_SERVICE_IFACE,
 				NULL, NULL, service_properties,
 				g_strdup(uuid), g_free) == FALSE) {
 		printf("Couldn't register service interface\n");
@@ -213,13 +217,13 @@ static char *register_service(DBusConnection *conn, const char *uuid)
 	return path;
 }
 
-static void create_services(DBusConnection *conn)
+static void create_services()
 {
 	char *service_path;
 	uint8_t level = 0;
 	int ret;
 
-	service_path = register_service(conn, IAS_UUID);
+	service_path = register_service(IAS_UUID);
 	if (service_path == NULL)
 		return;
 
@@ -227,11 +231,11 @@ static void create_services(DBusConnection *conn)
 	 * According to the IAS SPEC, reading <<Alert level>> is not alloweed.
 	 * "Value" is readable for testing purpose only.
 	 */
-	ret = register_characteristic(conn, ALERT_LEVEL_CHR_UUID, &level,
+	ret = register_characteristic(connection, ALERT_LEVEL_CHR_UUID, &level,
 						sizeof(level), service_path);
 	if (ret < 0) {
 		printf("Couldn't register Alert Level characteristic (IAS)\n");
-		g_dbus_unregister_interface(conn, service_path,
+		g_dbus_unregister_interface(connection, service_path,
 							GATT_SERVICE_IFACE);
 		g_free(service_path);
 		return;
@@ -372,25 +376,24 @@ static guint setup_signalfd(void)
 int main(int argc, char *argv[])
 {
 	GDBusClient *client;
-	DBusConnection *dbus_conn;
 	guint signal;
 
 	signal = setup_signalfd();
 	if (signal == 0)
 		return -errno;
 
-	dbus_conn = g_dbus_setup_bus(DBUS_BUS_SYSTEM, NULL, NULL);
+	connection = g_dbus_setup_bus(DBUS_BUS_SYSTEM, NULL, NULL);
 
 	main_loop = g_main_loop_new(NULL, FALSE);
 
-	g_dbus_attach_object_manager(dbus_conn);
+	g_dbus_attach_object_manager(connection);
 
 	printf("gatt-service unique name: %s\n",
-				dbus_bus_get_unique_name(dbus_conn));
+				dbus_bus_get_unique_name(connection));
 
-	create_services(dbus_conn);
+	create_services();
 
-	client = g_dbus_client_new(dbus_conn, "org.bluez", "/org/bluez");
+	client = g_dbus_client_new(connection, "org.bluez", "/org/bluez");
 
 	g_dbus_client_set_connect_watch(client, connect_handler, NULL);
 
@@ -401,7 +404,7 @@ int main(int argc, char *argv[])
 	g_source_remove(signal);
 
 	g_slist_free_full(services, g_free);
-	dbus_connection_unref(dbus_conn);
+	dbus_connection_unref(connection);
 
 	return 0;
 }
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH BlueZ v0 15/16] tools: Add setting Value property of gatt-service
From: Claudio Takahasi @ 2014-03-10 18:50 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: claudio.takahasi, Alvaro Silva
In-Reply-To: <1394477445-8987-1-git-send-email-claudio.takahasi@openbossa.org>

From: Alvaro Silva <alvaro.silva@openbossa.org>

This patch extends the gatt-service.c example adding a generic callback
to allow set the characteristic Value. It doesn't check for
characteristic properties yet.
---
 tools/gatt-service.c | 33 ++++++++++++++++++++++++++++++++-
 1 file changed, 32 insertions(+), 1 deletion(-)

diff --git a/tools/gatt-service.c b/tools/gatt-service.c
index 25528ca..481495c 100644
--- a/tools/gatt-service.c
+++ b/tools/gatt-service.c
@@ -35,6 +35,8 @@
 #include <dbus/dbus.h>
 #include <gdbus/gdbus.h>
 
+#include "src/error.h"
+
 #define GATT_MGR_IFACE			"org.bluez.GattManager1"
 #define GATT_SERVICE_IFACE		"org.bluez.GattService1"
 #define GATT_CHR_IFACE			"org.bluez.GattCharacteristic1"
@@ -81,9 +83,38 @@ static gboolean chr_get_value(const GDBusPropertyTable *property,
 	return TRUE;
 }
 
+static void chr_set_value(const GDBusPropertyTable *property,
+				DBusMessageIter *iter,
+				GDBusPendingPropertySet id, void *user_data)
+{
+	struct characteristic *chr = user_data;
+	DBusMessageIter array;
+	uint8_t *value;
+	int len;
+
+	printf("Set('Value', ...)\n");
+
+	if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY) {
+		printf("Invalid value for Set('Value'...)\n");
+		g_dbus_pending_property_error(id,
+					ERROR_INTERFACE ".InvalidArguments",
+					"Invalid arguments in method call");
+		return;
+	}
+
+	dbus_message_iter_recurse(iter, &array);
+	dbus_message_iter_get_fixed_array(&array, &value, &len);
+
+	g_free(chr->value);
+	chr->value = g_memdup(value, len);
+	chr->vlen = len;
+
+	g_dbus_pending_property_success(id);
+}
+
 static const GDBusPropertyTable chr_properties[] = {
 	{ "UUID",	"s",	chr_get_uuid },
-	{ "Value", "ay", chr_get_value, NULL, NULL },
+	{ "Value", "ay", chr_get_value, chr_set_value, NULL },
 	{ }
 };
 
-- 
1.8.3.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