Linux bluetooth development
 help / color / mirror / Atom feed
* [PATCH BlueZ 4/4] android: Disconnect AVRCP once A2DP is disconnected
From: Luiz Augusto von Dentz @ 2014-02-05 10:27 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1391596020-27679-1-git-send-email-luiz.dentz@gmail.com>

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

If A2DP is disconnected also disconnect AVRCP.
---
 android/a2dp.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/android/a2dp.c b/android/a2dp.c
index 962e7f5..731fa16 100644
--- a/android/a2dp.c
+++ b/android/a2dp.c
@@ -227,6 +227,8 @@ static void bt_a2dp_notify_state(struct a2dp_device *dev, uint8_t state)
 	if (state != HAL_A2DP_STATE_DISCONNECTED)
 		return;
 
+	bt_avrcp_disconnect(&dev->dst);
+
 	a2dp_device_free(dev);
 }
 
-- 
1.8.5.3


^ permalink raw reply related

* [PATCH BlueZ 3/4] android: Connect AVRCP once A2DP is connected
From: Luiz Augusto von Dentz @ 2014-02-05 10:26 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1391596020-27679-1-git-send-email-luiz.dentz@gmail.com>

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

In case of being the initiator of the A2DP connection also attempt to
connect AVRCP.
---
 android/a2dp.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/android/a2dp.c b/android/a2dp.c
index a215ce2..962e7f5 100644
--- a/android/a2dp.c
+++ b/android/a2dp.c
@@ -45,6 +45,7 @@
 #include "utils.h"
 #include "bluetooth.h"
 #include "avdtp.h"
+#include "avrcp.h"
 #include "audio-msg.h"
 #include "audio-ipc.h"
 
@@ -544,6 +545,7 @@ static void signaling_connect_cb(GIOChannel *chan, GError *err,
 			error("avdtp_discover: %s", strerror(-perr));
 			goto failed;
 		}
+		bt_avrcp_connect(&dev->dst);
 	} else /* Init idle timeout to discover */
 		dev->idle_id = g_timeout_add_seconds(IDLE_TIMEOUT, idle_timeout,
 									dev);
-- 
1.8.5.3


^ permalink raw reply related

* [PATCH BlueZ 2/4] android/AVRCP: Add bt_avrcp_disconnect
From: Luiz Augusto von Dentz @ 2014-02-05 10:26 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1391596020-27679-1-git-send-email-luiz.dentz@gmail.com>

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

This adds bt_avrcp_disconnect function which can be used to disconnect
AVRCP sessions.
---
 android/avrcp.c | 26 ++++++++++++++++++++++++++
 android/avrcp.h |  1 +
 2 files changed, 27 insertions(+)

diff --git a/android/avrcp.c b/android/avrcp.c
index 8600d98..f61ed34 100644
--- a/android/avrcp.c
+++ b/android/avrcp.c
@@ -135,6 +135,11 @@ static void avrcp_device_free(void *data)
 	if (dev->session)
 		avctp_shutdown(dev->session);
 
+	if (dev->io) {
+		g_io_channel_shutdown(dev->io, FALSE, NULL);
+		g_io_channel_unref(dev->io);
+	}
+
 	devices = g_slist_remove(devices, dev);
 	g_free(dev);
 }
@@ -338,3 +343,24 @@ void bt_avrcp_connect(const bdaddr_t *dst)
 	ba2str(&dev->dst, addr);
 	DBG("connecting to %s", addr);
 }
+
+void bt_avrcp_disconnect(const bdaddr_t *dst)
+{
+	struct avrcp_device *dev;
+	GSList *l;
+
+	DBG("");
+
+	l = g_slist_find_custom(devices, dst, device_cmp);
+	if (!l)
+		return;
+
+	dev = l->data;
+
+	if (dev->session) {
+		avctp_shutdown(dev->session);
+		return;
+	}
+
+	avrcp_device_free(dev);
+}
diff --git a/android/avrcp.h b/android/avrcp.h
index 7b0a5ed..4ad49e6 100644
--- a/android/avrcp.h
+++ b/android/avrcp.h
@@ -25,3 +25,4 @@ bool bt_avrcp_register(const bdaddr_t *addr);
 void bt_avrcp_unregister(void);
 
 void bt_avrcp_connect(const bdaddr_t *dst);
+void bt_avrcp_disconnect(const bdaddr_t *dst);
-- 
1.8.5.3


^ permalink raw reply related

* [PATCH BlueZ 1/4] android/AVRCP: Add bt_avrcp_connect
From: Luiz Augusto von Dentz @ 2014-02-05 10:26 UTC (permalink / raw)
  To: linux-bluetooth

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

This adds bt_avrcp_connect function which can be used to request AVRCP
connections.
---
 android/avrcp.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++-----
 android/avrcp.h |  2 ++
 2 files changed, 57 insertions(+), 5 deletions(-)

diff --git a/android/avrcp.c b/android/avrcp.c
index ef833df..8600d98 100644
--- a/android/avrcp.c
+++ b/android/avrcp.c
@@ -54,6 +54,7 @@ static GIOChannel *server = NULL;
 struct avrcp_device {
 	bdaddr_t	dst;
 	struct avctp	*session;
+	GIOChannel	*io;
 };
 
 static const struct ipc_handler cmd_handlers[] = {
@@ -197,17 +198,20 @@ static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
 	}
 
 	ba2str(&dst, address);
-	DBG("Incoming connection from %s", address);
 
 	l = g_slist_find_custom(devices, &dst, device_cmp);
 	if (l) {
-		error("Unexpected connection");
-		return;
+		dev = l->data;
+		if (dev->session) {
+			error("Unexpected connection");
+			return;
+		}
+	} else {
+		DBG("Incoming connection from %s", address);
+		dev = avrcp_device_new(&dst);
 	}
 
 	fd = g_io_channel_unix_get_fd(chan);
-
-	dev = avrcp_device_new(&dst);
 	dev->session = avctp_new(fd, imtu, omtu, 0x0100);
 
 	if (!dev->session) {
@@ -222,6 +226,11 @@ static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
 
 	g_io_channel_set_close_on_unref(chan, FALSE);
 
+	if (dev->io) {
+		g_io_channel_unref(dev->io);
+		dev->io = NULL;
+	}
+
 	DBG("%s connected", address);
 }
 
@@ -288,3 +297,44 @@ void bt_avrcp_unregister(void)
 		server = NULL;
 	}
 }
+
+static bool avrcp_device_connect(struct avrcp_device *dev, BtIOConnect cb)
+{
+	GError *err = NULL;
+
+	dev->io = bt_io_connect(cb, dev, NULL, &err,
+					BT_IO_OPT_SOURCE_BDADDR, &adapter_addr,
+					BT_IO_OPT_DEST_BDADDR, &dev->dst,
+					BT_IO_OPT_PSM, L2CAP_PSM_AVCTP,
+					BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
+					BT_IO_OPT_INVALID);
+	if (err) {
+		error("%s", err->message);
+		g_error_free(err);
+		return false;
+	}
+
+	return true;
+}
+
+void bt_avrcp_connect(const bdaddr_t *dst)
+{
+	struct avrcp_device *dev;
+	char addr[18];
+	GSList *l;
+
+	DBG("");
+
+	l = g_slist_find_custom(devices, dst, device_cmp);
+	if (l)
+		return;
+
+	dev = avrcp_device_new(dst);
+	if (!avrcp_device_connect(dev, connect_cb)) {
+		avrcp_device_free(dev);
+		return;
+	}
+
+	ba2str(&dev->dst, addr);
+	DBG("connecting to %s", addr);
+}
diff --git a/android/avrcp.h b/android/avrcp.h
index 6fe7fbf..7b0a5ed 100644
--- a/android/avrcp.h
+++ b/android/avrcp.h
@@ -23,3 +23,5 @@
 
 bool bt_avrcp_register(const bdaddr_t *addr);
 void bt_avrcp_unregister(void);
+
+void bt_avrcp_connect(const bdaddr_t *dst);
-- 
1.8.5.3


^ permalink raw reply related

* Re: [PATCH] android/pts: Update PICS and PTS for AVCTP
From: Szymon Janc @ 2014-02-05  9:55 UTC (permalink / raw)
  To: Sebastian Chlad; +Cc: linux-bluetooth
In-Reply-To: <1391505632-5306-1-git-send-email-sebastianx.chlad@intel.com>

Hi Sebastian,

On Tuesday 04 of February 2014 11:20:32 Sebastian Chlad wrote:
> Since we do not support AVCTP fragmentation for now we shell set PICS
> settings for AVCTP accordingly as well as set respective PTS test cases
> as N/A
> ---
>  android/pics-avctp.txt | 2 +-
>  android/pts-avctp.txt  | 4 ++--
>  2 files changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/android/pics-avctp.txt b/android/pics-avctp.txt
> index 939ffdb..269bf08 100644
> --- a/android/pics-avctp.txt
> +++ b/android/pics-avctp.txt
> @@ -58,7 +58,7 @@ TSPC_AVCTP_2_14	False		Support for multiple AVCTP channel establishment
>  -------------------------------------------------------------------------------
>  Parameter Name	Selected	Description
>  -------------------------------------------------------------------------------
> -TSPC_AVCTP_3_1	True (*)	Message fragmentation (O)
> +TSPC_AVCTP_3_1	False		Message fragmentation (O)
>  TSPC_AVCTP_3_2	True		Transaction label management (M)
>  TSPC_AVCTP_3_3	True		Packet type field management (M)
>  TSPC_AVCTP_3_4	True		Message type field management (M)
> diff --git a/android/pts-avctp.txt b/android/pts-avctp.txt
> index 4090ec0..72a6373 100644
> --- a/android/pts-avctp.txt
> +++ b/android/pts-avctp.txt
> @@ -37,6 +37,6 @@ TC_TG_CCM_BV_04_C	PASS	avtest --device hci0 --avctp --send x <bdaddr>
>  TC_TG_NFR_BV_02_C	PASS	avtest --device hci0 --avctp --send x <bdaddr>
>  TC_TG_NFR_BV_03_C	PASS	avtest --device hci0 --avctp --send x <bdaddr>
>  TC_TG_NFR_BI_01_C	PASS
> -TC_TG_FRA_BV_02_C	FAIL
> -TC_TG_FRA_BV_03_C	INC
> +TC_TG_FRA_BV_02_C	N/A	Fragmentation not supported
> +TC_TG_FRA_BV_03_C	N/A	Fragmentation not supported
>  -------------------------------------------------------------------------------
> 

Pushed, thanks.

-- 
Best regards, 
Szymon Janc

^ permalink raw reply

* Re: [PATCH BlueZ] audio/AVRCP: Fix checking for handler pointer instead of pdu_id
From: Luiz Augusto von Dentz @ 2014-02-05  9:37 UTC (permalink / raw)
  To: linux-bluetooth@vger.kernel.org
In-Reply-To: <1391420434-17873-1-git-send-email-luiz.dentz@gmail.com>

Hi,

On Mon, Feb 3, 2014 at 11:40 AM, Luiz Augusto von Dentz
<luiz.dentz@gmail.com> wrote:
> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
>
> The code may not find a valid handler for the pdu_id, in that case the
> handler would not be NULL because the handlers table is not NULL
> terminated, instead the code should check if pdu_id really matches.
> ---
>  profiles/audio/avrcp.c | 8 ++++----
>  1 file changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/profiles/audio/avrcp.c b/profiles/audio/avrcp.c
> index 12f7faa..4532d85 100644
> --- a/profiles/audio/avrcp.c
> +++ b/profiles/audio/avrcp.c
> @@ -1673,7 +1673,7 @@ static size_t handle_vendordep_pdu(struct avctp *conn, uint8_t transaction,
>                         break;
>         }
>
> -       if (!handler || handler->code != *code) {
> +       if (handler->pdu_id != pdu->pdu_id || handler->code != *code) {
>                 pdu->params[0] = AVRCP_STATUS_INVALID_COMMAND;
>                 goto err_metadata;
>         }
> @@ -1734,12 +1734,12 @@ static size_t handle_browsing_pdu(struct avctp *conn,
>
>         for (handler = browsing_handlers; handler->pdu_id; handler++) {
>                 if (handler->pdu_id == pdu->pdu_id)
> -                       break;
> +                       goto done;
>         }
>
> -       if (handler == NULL || handler->func == NULL)
> -               return avrcp_browsing_general_reject(operands);
> +       return avrcp_browsing_general_reject(operands);
>
> +done:
>         session->transaction = transaction;
>         handler->func(session, pdu, transaction);
>         return AVRCP_BROWSING_HEADER_LENGTH + ntohs(pdu->param_len);
> --
> 1.8.4.2

Pushed.


-- 
Luiz Augusto von Dentz

^ permalink raw reply

* [PATCH v2] android: Add support for Valgrind in debug variants
From: Andrzej Kaczmarek @ 2014-02-05  9:14 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Andrzej Kaczmarek
In-Reply-To: <1391591653-17254-1-git-send-email-andrzej.kaczmarek@tieto.com>

This patch allows bluetoothd to be run with Valgrind easily in debug
variants.

For userdebug and eng variants bluetoothd is renamed to bluetoothd-main
and bluetoothd acts a wrapper to launch it either with or without
Valgrind (this is decided by value of persist.sys.bluetooth.valgrind
property).
---
 android/Android.mk           | 42 +++++++++++++++++++++++++++++
 android/bluetoothd-wrapper.c | 63 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 105 insertions(+)
 create mode 100644 android/bluetoothd-wrapper.c

diff --git a/android/Android.mk b/android/Android.mk
index 20105e6..52745fe 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -82,7 +82,15 @@ $(shell mkdir -p $(LOCAL_PATH)/bluez/lib/bluetooth)
 $(foreach file,$(lib_headers), $(shell ln -sf ../$(file) $(LOCAL_PATH)/bluez/lib/bluetooth/$(file)))
 
 LOCAL_MODULE_TAGS := optional
+
+# for userdebug/eng this module is bluetoothd-main since bluetoothd is used as
+# wrapper to launch bluetooth with Valgrind
+ifneq (,$(filter userdebug eng,$(TARGET_BUILD_VARIANT)))
+LOCAL_MODULE := bluetoothd-main
+LOCAL_STRIP_MODULE := false
+else
 LOCAL_MODULE := bluetoothd
+endif
 
 include $(BUILD_EXECUTABLE)
 
@@ -406,3 +414,37 @@ LOCAL_CFLAGS:= \
 LOCAL_MODULE := libsbc
 
 include $(BUILD_SHARED_LIBRARY)
+
+ifneq (,$(filter userdebug eng,$(TARGET_BUILD_VARIANT)))
+
+#
+# bluetoothd (debug)
+# this is just a wrapper used in userdebug/eng to launch bluetoothd-main
+# with/without Valgrind
+#
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+	bluez/android/bluetoothd-wrapper.c
+
+LOCAL_CFLAGS := $(BLUEZ_COMMON_CFLAGS)
+
+LOCAL_SHARED_LIBRARIES := \
+	libcutils \
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_EXECUTABLES)
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE := bluetoothd
+
+LOCAL_REQUIRED_MODULES := \
+	bluetoothd-main \
+	valgrind \
+	memcheck-$(TARGET_ARCH)-linux \
+	vgpreload_core-$(TARGET_ARCH)-linux \
+	vgpreload_memcheck-$(TARGET_ARCH)-linux \
+	default.supp
+
+include $(BUILD_EXECUTABLE)
+
+endif
\ No newline at end of file
diff --git a/android/bluetoothd-wrapper.c b/android/bluetoothd-wrapper.c
new file mode 100644
index 0000000..eb59822
--- /dev/null
+++ b/android/bluetoothd-wrapper.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2014 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <cutils/properties.h>
+
+#define PROPERTY_NAME "persist.sys.bluetooth.valgrind"
+
+#define VALGRIND_BIN "/system/bin/valgrind"
+
+#define BLUETOOTHD_BIN "/system/bin/bluetoothd-main"
+
+int main(int argc, char *argv[])
+{
+	char value[PROPERTY_VALUE_MAX];
+	char *prg_argv[4];
+	char *prg_envp[3];
+
+	if (property_get(PROPERTY_NAME, value, "") <= 0)
+		goto run_bluetoothd;
+
+	if (strcasecmp(value, "true") && atoi(value) == 0)
+		goto run_bluetoothd;
+
+	prg_argv[0] = VALGRIND_BIN;
+	prg_argv[1] = "--leak-check=full";
+	prg_argv[2] = BLUETOOTHD_BIN;
+	prg_argv[3] = NULL;
+
+	prg_envp[0] = "G_SLICE=always-malloc";
+	prg_envp[1] = "G_DEBUG=gc-friendly";
+	prg_envp[2] = NULL;
+
+	execve(prg_argv[0], prg_argv, prg_envp);
+
+run_bluetoothd:
+	prg_argv[0] = BLUETOOTHD_BIN;
+	prg_argv[1] = NULL;
+
+	prg_envp[0] = NULL;
+
+	execve(prg_argv[0], prg_argv, prg_envp);
+
+	return 0;
+}
-- 
1.8.5.3


^ permalink raw reply related

* [PATCH v2] Valgrind on Android
From: Andrzej Kaczmarek @ 2014-02-05  9:14 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Andrzej Kaczmarek

v1 -> v2
Valgrind can be enabled using property (persist.sys.bluetooth.valgrind)

In userdebug/eng variants bluetoothd is renamed to bluetoothd-main and
bluetoothd is simple wrapper to check property value and execute either
bluetoothd-main or valgrind. This way using Valgrind is transparent from
system point of view (we do not need to change init.bluetooth.rc, no
special build flags and logcat still shows bluetoothd as tagname).

Andrzej Kaczmarek (1):
  android: Add support for Valgrind in debug variants

 android/Android.mk           | 42 +++++++++++++++++++++++++++++
 android/bluetoothd-wrapper.c | 63 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 105 insertions(+)
 create mode 100644 android/bluetoothd-wrapper.c

-- 
1.8.5.3


^ permalink raw reply

* Re: [PATCH 06/13] android/handsfree: Add SDP record for AG
From: Szymon Janc @ 2014-02-05  9:10 UTC (permalink / raw)
  To: Andrei Emeltchenko; +Cc: linux-bluetooth
In-Reply-To: <20140203075616.GB2930@aemeltch-MOBL1>

Hi Andrei,

On Monday 03 of February 2014 09:56:18 Andrei Emeltchenko wrote:
> Hi Szymon,
> 
> On Sun, Feb 02, 2014 at 10:09:17PM +0100, Szymon Janc wrote:
> > Service Name: Hands-Free Audio GatewayService RecHandle: 0x10001
> > Service Class ID List:
> >   "Handsfree Audio Gateway" (0x111f)
> >   "Generic Audio" (0x1203)
> > Protocol Descriptor List:
> >   "L2CAP" (0x0100)
> >   "RFCOMM" (0x0003)
> >     Channel: 13
> > Profile Descriptor List:
> >   "Handsfree" (0x111e)
> >     Version: 0x0106
> > ---
> >  android/handsfree.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++++
> >  1 file changed, 97 insertions(+)
> > 
> > diff --git a/android/handsfree.c b/android/handsfree.c
> > index 3c0d52b..d2dc543 100644
> > --- a/android/handsfree.c
> > +++ b/android/handsfree.c
> > @@ -29,12 +29,19 @@
> >  #include <glib.h>
> >  
> >  #include "lib/bluetooth.h"
> > +#include "lib/sdp.h"
> > +#include "lib/sdp_lib.h"
> >  #include "handsfree.h"
> > +#include "bluetooth.h"
> >  #include "src/log.h"
> >  #include "hal-msg.h"
> >  #include "ipc.h"
> >  
> > +#define HFP_AG_CHANNEL 13
> > +#define HFP_AG_FEATURES 0
> > +
> >  static bdaddr_t adapter_addr;
> > +static uint32_t record_id = 0;
> >  
> >  static void handle_connect(const void *buf, uint16_t len)
> >  {
> > @@ -189,12 +196,99 @@ static const struct ipc_handler cmd_handlers[] = {
> >  			sizeof(struct hal_cmd_handsfree_phone_state_change)},
> >  };
> >  
> > +static sdp_record_t *handsfree_ag_record(void)
> > +{
> > +	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
> > +	uuid_t root_uuid, svclass_uuid, ga_svclass_uuid;
> > +	uuid_t l2cap_uuid, rfcomm_uuid;
> > +	sdp_profile_desc_t profile;
> > +	sdp_list_t *aproto, *proto[2];
> > +	sdp_record_t *record;
> > +	sdp_data_t *channel, *features;
> > +	uint8_t netid = 0x01;
> > +	uint16_t sdpfeat;
> > +	sdp_data_t *network;
> > +	uint8_t ch = HFP_AG_CHANNEL;
> > +
> > +	record = sdp_record_alloc();
> > +	if (!record)
> > +		return NULL;
> > +
> > +	network = sdp_data_alloc(SDP_UINT8, &netid);
> > +	if (!network) {
> > +		sdp_record_free(record);
> > +		return NULL;
> > +	}
> > +
> > +	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
> > +	root = sdp_list_append(0, &root_uuid);
> > +	sdp_set_browse_groups(record, root);
> > +
> > +	sdp_uuid16_create(&svclass_uuid, HANDSFREE_AGW_SVCLASS_ID);
> > +	svclass_id = sdp_list_append(0, &svclass_uuid);
> > +	sdp_uuid16_create(&ga_svclass_uuid, GENERIC_AUDIO_SVCLASS_ID);
> > +	svclass_id = sdp_list_append(svclass_id, &ga_svclass_uuid);
> > +	sdp_set_service_classes(record, svclass_id);
> > +
> > +	sdp_uuid16_create(&profile.uuid, HANDSFREE_PROFILE_ID);
> > +	profile.version = 0x0106;
> > +	pfseq = sdp_list_append(0, &profile);
> > +	sdp_set_profile_descs(record, pfseq);
> > +
> > +	sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
> > +	proto[0] = sdp_list_append(0, &l2cap_uuid);
> > +	apseq = sdp_list_append(0, proto[0]);
> > +
> > +	sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID);
> > +	proto[1] = sdp_list_append(0, &rfcomm_uuid);
> > +	channel = sdp_data_alloc(SDP_UINT8, &ch);
> > +	proto[1] = sdp_list_append(proto[1], channel);
> > +	apseq = sdp_list_append(apseq, proto[1]);
> > +
> > +	sdpfeat = HFP_AG_FEATURES;
> > +	features = sdp_data_alloc(SDP_UINT16, &sdpfeat);
> > +	sdp_attr_add(record, SDP_ATTR_SUPPORTED_FEATURES, features);
> > +
> > +	aproto = sdp_list_append(0, apseq);
> > +	sdp_set_access_protos(record, aproto);
> > +
> > +	sdp_set_info_attr(record, "Hands-Free Audio Gateway", 0, 0);
> > +
> > +	sdp_attr_add(record, SDP_ATTR_EXTERNAL_NETWORK, network);
> > +
> > +	sdp_data_free(channel);
> > +	sdp_list_free(proto[0], 0);
> 
> We have agreed to use NULL for zero pointers.

I've miss that comment, but this is now fixed by follow-up patch. 

-- 
Best regards, 
Szymon Janc

^ permalink raw reply

* Re: [PATCH 00/13] Initial code for handsfree support
From: Szymon Janc @ 2014-02-05  9:10 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1391375364-27106-1-git-send-email-szymon.janc@tieto.com>

On Sunday 02 of February 2014 22:09:11 Szymon Janc wrote:
> Hi,
> 
> This adds initial support for HFP. HAL library is complete, for daemon
> only support for RFCOMM connection handling.
> 
> There is also minimal set of AT handling needed for SLC establishment
> (proper AT parsing code is still missing).
> 
> Comments are welcome.
> 
> BR
> Szymon Janc
> 
> Szymon Janc (13):
>   android/handsfree: Add initial files
>   android/handsfree: Add commands and events definition to IPC header
>   android/handsfree: Add stubs for commands handlers
>   android/hal-handsfree: Implement notifications handling
>   android/hal-handsfree: Implement sending commands
>   android/handsfree: Add SDP record for AG
>   android/handsfree: Add support for RFCOMM connection handling
>   android/handsfree: Add initial code for AT commands processing
>   android/handsfree: Add connect command handling
>   android/handsfree: Add disconnect command handling
>   android/handsfree: Add AT+BRSF command support
>   android/handsfree: Add support for AT+CIND command
>   android/handsfree: Add support for AT+CMER command
> 
>  android/Android.mk      |   2 +
>  android/Makefile.am     |   4 +
>  android/hal-bluetooth.c |   3 +
>  android/hal-handsfree.c | 598 +++++++++++++++++++++++++++++++++++++
>  android/hal-msg.h       | 208 +++++++++++++
>  android/hal.h           |   2 +
>  android/handsfree.c     | 763 ++++++++++++++++++++++++++++++++++++++++++++++++
>  android/handsfree.h     |  25 ++
>  android/main.c          |  14 +
>  9 files changed, 1619 insertions(+)
>  create mode 100644 android/hal-handsfree.c
>  create mode 100644 android/handsfree.c
>  create mode 100644 android/handsfree.h
> 
> 

Patches 1-10 are now pushed.

-- 
Best regards, 
Szymon Janc

^ permalink raw reply

* Re: [PATCH v2 1/3] android/bluetooth: Add threshold to RSSI change
From: Szymon Janc @ 2014-02-05  8:48 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1391531663-13143-1-git-send-email-szymon.janc@tieto.com>

On Tuesday 04 of February 2014 17:34:21 Szymon Janc wrote:
> There is no need to report very small RSSI changes.
> ---
> v2: Fix name and use abs()
> 
>  android/bluetooth.c | 8 +++++++-
>  1 file changed, 7 insertions(+), 1 deletion(-)
> 
> diff --git a/android/bluetooth.c b/android/bluetooth.c
> index d74d792..5aed4af 100644
> --- a/android/bluetooth.c
> +++ b/android/bluetooth.c
> @@ -1045,6 +1045,12 @@ static uint8_t bdaddr_type2android(uint8_t type)
>  	return HAL_TYPE_LE;
>  }
>  
> +static bool rssi_above_threshold(int old, int new)
> +{
> +	/* only 8 dBm or more */
> +	return abs(old - new) >= 8;
> +}
> +
>  static void update_found_device(const bdaddr_t *bdaddr, uint8_t bdaddr_type,
>  					int8_t rssi, bool confirm,
>  					const uint8_t *data, uint8_t data_len)
> @@ -1113,7 +1119,7 @@ static void update_found_device(const bdaddr_t *bdaddr, uint8_t bdaddr_type,
>  		(*num_prop)++;
>  	}
>  
> -	if (rssi) {
> +	if (rssi && rssi_above_threshold(dev->rssi, rssi)) {
>  		dev->rssi = rssi;
>  
>  		size += fill_hal_prop(buf + size, HAL_PROP_DEVICE_RSSI,
> 

Pushed.

-- 
Best regards, 
Szymon Janc

^ permalink raw reply

* Re: possible bug in blueZ 5.8 gatt tool or library
From: Anderson Lizardo @ 2014-02-04 23:05 UTC (permalink / raw)
  To: Caleb Reinhold; +Cc: BlueZ development
In-Reply-To: <000201cf21ed$d18f02d0$74ad0870$@lampreynetworks.com>

Hi Caleb,

On Tue, Feb 4, 2014 at 5:12 PM, Caleb Reinhold
<creinhold@lampreynetworks.com> wrote:
> We are working with the 5.8 version of the library, kernel version 3.12.9,
> bluetoothctl, and gatttool when we encountered a possible error.
> We expected on the reconnection of two bonded devices, one of which had
> stored measurements, that data would transfer. When running gatt tool in
> medium security the first measurement to be indicated was lost.

First of all, gatttool is a developer tool, and it is far from being a
compliant GATT endpoint (e.g. it does not report to requests, which is
mandatory by the spec). With moderate effort though, the missing
features can be added.

> However upon attempting to reconnect to the simulated agent device with
> medium security two unexpected behaviors occurred. First, and more
> immediately apparent was that the simulated agent did not receive a
> confirmation of the indication. A slightly closer look using the hcidump,
> trying to find what had happened, showed that the indication had arrived at
> the hci layer but was not received at events_handler.

Are you using gatttool in interactive mode (i.e. the -I option) ? If
yes, try first connecting to the device with "connect" followed by
setting the security level to medium with "sec-level medium". This
will imitate the behavior of the BlueZ daemon when connecting to LE
devices. Also be sure to use the "--listen" option so the confirmation
is sent by gatttool.

Let us know if it works :)

> While the indication
> is sent very swiftly upon the reconnection of the devices we understand this
> to be the manner in which low energy devices are supposed to behave given
> stored measurements and a bonded device.

You are correct that this is the expected behavior. But gatttool is
far from perfect. Did you try implementing a BlueZ plugin?

Best Regards,
-- 
Anderson Lizardo
http://www.indt.org/?lang=en
INdT - Manaus - Brazil

^ permalink raw reply

* Re: Bluetooth qualification, AVDTP test case
From: Luiz Augusto von Dentz @ 2014-02-04 22:06 UTC (permalink / raw)
  To: Artem Rakhov; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <CAD81oNbWcjW_vEzf-C8VkS9Mkh92jdaKLHc_sTY9yt1wvboM3g@mail.gmail.com>

Hi Artem,

On Tue, Feb 4, 2014 at 10:36 PM, Artem Rakhov <arakhov@google.com> wrote:
> Hi Luiz,
>
> We are currently working on the Bluetooth SIG qualification, and we are
> failing AVDTP test case "TP/SIG/SMG/BI-28-C". I've found your test in the
> BlueZ source (unit/test-avdtp.c), which seems to contain implementation of
> this test case. Could you please give us some clue on how to use it to do
> the actual testing and to produce a log?

Interesting, apparently the test spec suggests resetting the signal
identifier to 0x00:

Pass verdict
The lower tester receives the AVDTP signaling message with the fields:
Transaction_label = Transaction LowerTester
Other 10 bits = All set to '0'.

While the spec suggests to keep the original signal identifier that is
being rejected see Table 8.42: General Reject response format.

We are following the spec text in this respect, thus our unit test
checks for the original signal identifier skipping the RFA bits which
is what our AVDTP implementation does when responding when receiving
such command, either way it is easy to fix but we probably need to
file an errata so the spec and test spec are more consistent regarding
general reject response.

For the purpose of qualification I think we need the full trace up to
HCI so the unit test are not enough, but there are plans to do that
via emulator.

-- 
Luiz Augusto von Dentz

^ permalink raw reply

* Re: How do you install bluez for development?
From: Vinicius Costa Gomes @ 2014-02-04 21:57 UTC (permalink / raw)
  To: Alejandro Exojo; +Cc: linux-bluetooth
In-Reply-To: <CACMtdhhnvG_PopNn185npxi2nSqzFSLXthoh6PPPTh4SGj_uiA@mail.gmail.com>

Hi Alejandro,

On 08:28 Tue 04 Feb, Alejandro Exojo wrote:
> 2014-02-03 Vinicius Costa Gomes <vcgomes@gmail.com>:
> >> Feb 03 17:14:38 PC-MW03 systemd[1]: Starting Bluetooth service...
> >> Feb 03 17:14:38 PC-MW03 bluetoothd[22571]: Bluetooth daemon 5.14
> >> Feb 03 17:14:38 PC-MW03 systemd[1]: Started Bluetooth service.
> >> Feb 03 17:14:38 PC-MW03 systemd[1]: Starting Bluetooth.
> >> Feb 03 17:14:38 PC-MW03 systemd[1]: Reached target Bluetooth.
> >> Feb 03 17:14:38 PC-MW03 bluetoothd[22571]: Failed to access management interface
> >
> > Two probable causes, your kernel is older than 3.4, or the user that is running
> > bluetoothd doesn't have the CAP_NET_ADMIN capability.
>
> True! I was running 3.2. I've installed a more recent one, and I got
> it working. Thank you very much, I would not have thought of the
> kernel at all.
>
> How come that at least 3.4 is needed?

That was the kernel version that enabled the management interface by default, which is a
runtime requirement for BlueZ 5.x.

>
> Thank you again.
>
> Cheers.
> --
> Alejandro Exojo Piqueras
>
> ModpoW, S.L.
> Technova LaSalle | Sant Joan de la Salle 42 | 08022 Barcelona | www.modpow.es
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


Cheers,
--
Vinicius

^ permalink raw reply

* possible bug in blueZ 5.8 gatt tool or library
From: Caleb Reinhold @ 2014-02-04 21:12 UTC (permalink / raw)
  To: linux-bluetooth

[-- Attachment #1: Type: text/plain, Size: 1663 bytes --]

Hello all,

I am participating in an effort to make use of the BlueZ libraries to pull
data from Bluetooth Low Energy health devices. 
We are working with the 5.8 version of the library, kernel version 3.12.9,
bluetoothctl, and gatttool when we encountered a possible error.
We expected on the reconnection of two bonded devices, one of which had
stored measurements, that data would transfer. When running gatt tool in
medium security the first measurement to be indicated was lost.
First we used Bluetooth control to pair with the simulated agent device (a
thermometer). Then we disconnected with bluetoothctl and connected with
gatttool in order to write to the C3D (client characteristic configuration
descriptors). After setting the C3D to indicate, we transferred a
measurement successfully.  Up until this point we saw no unexpected
difference in behavior between low and medium security on the gatttool.
However upon attempting to reconnect to the simulated agent device with
medium security two unexpected behaviors occurred. First, and more
immediately apparent was that the simulated agent did not receive a
confirmation of the indication. A slightly closer look using the hcidump,
trying to find what had happened, showed that the indication had arrived at
the hci layer but was not received at events_handler.  While the indication
is sent very swiftly upon the reconnection of the devices we understand this
to be the manner in which low energy devices are supposed to behave given
stored measurements and a bonded device.
Records of hcidumps are attached.

Caleb Reinhold

P.S. Resending after failing to attach traces

[-- Attachment #2: hci_dump.txt --]
[-- Type: text/plain, Size: 4870 bytes --]

< HCI Command: LE Create Connection (0x08|0x000d) plen 25                     [hci0] 5199.285444
        Scan interval: 60.000 msec (0x0060)
        Scan window: 30.000 msec (0x0030)
        Filter policy: White list is not used (0x00)
        Peer address type: Public (0x00)
        Peer address: 00:02:72:C6:A0:6B (CC&C Technologies, Inc.)
        Own address type: Public (0x00)
        Min connection interval: 50.00 msec (0x0028)
        Max connection interval: 70.00 msec (0x0038)
        Connection latency: 0x0000
        Supervision timeout: 420 msec (0x002a)
        Min connection length: 0.000 msec (0x0000)
        Max connection length: 0.000 msec (0x0000)
> HCI Event: Command Status (0x0f) plen 4                                     [hci0] 5199.288196
      LE Create Connection (0x08|0x000d) ncmd 1
        Status: Success (0x00)
> HCI Event: LE Meta Event (0x3e) plen 19                                     [hci0] 5209.096157
      LE Connection Complete (0x01)
        Status: Success (0x00)
        Handle: 64
        Role: Master (0x00)
        Peer address type: Public (0x00)
        Peer address: 00:02:72:C6:A0:6B (CC&C Technologies, Inc.)
        Connection interval: 67.50 msec (0x0036)
        Connection latency: 0.00 msec (0x0000)
        Supervision timeout: 420 msec (0x002a)
        Master clock accuracy: 0x05
@ Device Connected: 00:02:72:C6:A0:6B (1) flags 0x0000
> ACL Data RX: Handle 64 flags 0x02 dlen 19                                   [hci0] 5209.129475
      ATT: Handle Value Indication (0x1d) len 14
        Handle: 0x0004
          Data: 0363000000de0702030f1b0e
< ACL Data TX: Handle 64 flags 0x00 dlen 5                                    [hci0] 5209.129824
      ATT: Handle Value Confirmation (0x1e) len 0
> HCI Event: Number of Completed Packets (0x13) plen 5                        [hci0] 5209.338106
        Num handles: 1
        Handle: 64
        Count: 1
< HCI Command: Disconnect (0x01|0x0006) plen 3                                [hci0] 5258.609760
        Handle: 64
        Reason: Remote User Terminated Connection (0x13)
> HCI Event: Command Status (0x0f) plen 4                                     [hci0] 5258.611935
      Disconnect (0x01|0x0006) ncmd 1
        Status: Success (0x00)
> HCI Event: Disconnect Complete (0x05) plen 4                                [hci0] 5258.674959
        Status: Success (0x00)
        Handle: 64
        Reason: Connection Terminated By Local Host (0x16)
@ Device Disconnected: 00:02:72:C6:A0:6B (1) reason 2

        

        
< HCI Command: LE Create Connection (0x08|0x000d) plen 25                     [hci0] 5302.994402
        Scan interval: 60.000 msec (0x0060)
        Scan window: 30.000 msec (0x0030)
        Filter policy: White list is not used (0x00)
        Peer address type: Public (0x00)
        Peer address: 00:02:72:C6:A0:6B (CC&C Technologies, Inc.)
        Own address type: Public (0x00)
        Min connection interval: 50.00 msec (0x0028)
        Max connection interval: 70.00 msec (0x0038)
        Connection latency: 0x0000
        Supervision timeout: 420 msec (0x002a)
        Min connection length: 0.000 msec (0x0000)
        Max connection length: 0.000 msec (0x0000)
> HCI Event: Command Status (0x0f) plen 4                                     [hci0] 5302.996878
      LE Create Connection (0x08|0x000d) ncmd 1
        Status: Success (0x00)
> HCI Event: LE Meta Event (0x3e) plen 19                                     [hci0] 5311.264930
      LE Connection Complete (0x01)
        Status: Success (0x00)
        Handle: 64
        Role: Master (0x00)
        Peer address type: Public (0x00)
        Peer address: 00:02:72:C6:A0:6B (CC&C Technologies, Inc.)
        Connection interval: 67.50 msec (0x0036)
        Connection latency: 0.00 msec (0x0000)
        Supervision timeout: 420 msec (0x002a)
        Master clock accuracy: 0x05
< HCI Command: LE Start Encryption (0x08|0x0019) plen 28                      [hci0] 5311.265128
        Handle: 64
        Random number: 0d996e4936b9603f
        Encryption diversifier: 0x13a1
        Long term key: d43f4e489cc5b0746f86eac218c976e9
@ Device Connected: 00:02:72:C6:A0:6B (1) flags 0x0000
> HCI Event: Command Status (0x0f) plen 4                                     [hci0] 5311.267895
      LE Start Encryption (0x08|0x0019) ncmd 1
        Status: Success (0x00)
> ACL Data RX: Handle 64 flags 0x02 dlen 19                                   [hci0] 5311.326262
      ATT: Handle Value Indication (0x1d) len 14
        Handle: 0x0004
          Data: 0363000000de0702030f1c38
> HCI Event: Encryption Change (0x08) plen 4                                  [hci0] 5311.730919
        Status: Success (0x00)
        Handle: 64
        Encryption: Enabled with AES-CCM (0x01)
        

[-- Attachment #3: BlueZ Trace-2 indications.txt --]
[-- Type: text/plain, Size: 2797 bytes --]

< HCI Command: LE Create Connection (0x08|0x000d) plen 25                     [hci0] 5302.994402
        Scan interval: 60.000 msec (0x0060)
        Scan window: 30.000 msec (0x0030)
        Filter policy: White list is not used (0x00)
        Peer address type: Public (0x00)
        Peer address: 00:02:72:C6:A0:6B (CC&C Technologies, Inc.)
        Own address type: Public (0x00)
        Min connection interval: 50.00 msec (0x0028)
        Max connection interval: 70.00 msec (0x0038)
        Connection latency: 0x0000
        Supervision timeout: 420 msec (0x002a)
        Min connection length: 0.000 msec (0x0000)
        Max connection length: 0.000 msec (0x0000)
> HCI Event: Command Status (0x0f) plen 4                                     [hci0] 5302.996878
      LE Create Connection (0x08|0x000d) ncmd 1
        Status: Success (0x00)
> HCI Event: LE Meta Event (0x3e) plen 19                                     [hci0] 5311.264930
      LE Connection Complete (0x01)
        Status: Success (0x00)
        Handle: 64
        Role: Master (0x00)
        Peer address type: Public (0x00)
        Peer address: 00:02:72:C6:A0:6B (CC&C Technologies, Inc.)
        Connection interval: 67.50 msec (0x0036)
        Connection latency: 0.00 msec (0x0000)
        Supervision timeout: 420 msec (0x002a)
        Master clock accuracy: 0x05
< HCI Command: LE Start Encryption (0x08|0x0019) plen 28                      [hci0] 5311.265128
        Handle: 64
        Random number: 0d996e4936b9603f
        Encryption diversifier: 0x13a1
        Long term key: d43f4e489cc5b0746f86eac218c976e9
@ Device Connected: 00:02:72:C6:A0:6B (1) flags 0x0000
> HCI Event: Command Status (0x0f) plen 4                                     [hci0] 5311.267895
      LE Start Encryption (0x08|0x0019) ncmd 1
        Status: Success (0x00)
> ACL Data RX: Handle 64 flags 0x02 dlen 19                                   [hci0] 5311.326262
      ATT: Handle Value Indication (0x1d) len 14
        Handle: 0x0004
          Data: 0363000000de0702030f1c38
> HCI Event: Encryption Change (0x08) plen 4                                  [hci0] 5311.730919
        Status: Success (0x00)
        Handle: 64
        Encryption: Enabled with AES-CCM (0x01)
> ACL Data RX: Handle 64 flags 0x02 dlen 19                                   [hci0] 5556.355293
      ATT: Handle Value Indication (0x1d) len 14
        Handle: 0x0004
          Data: 0363000000de0702030f2101
< ACL Data TX: Handle 64 flags 0x00 dlen 5                                    [hci0] 5556.355579
      ATT: Handle Value Confirmation (0x1e) len 0
> HCI Event: Number of Completed Packets (0x13) plen 5                        [hci0] 5556.622163
        Num handles: 1
        Handle: 64
        Count: 1

^ permalink raw reply

* possible bug in blueZ 5.8 gatt tool or library
From: Caleb Reinhold @ 2014-02-04 21:08 UTC (permalink / raw)
  To: linux-bluetooth

Hello all,

I am participating in an effort to make use of the BlueZ libraries to pull
data from Bluetooth Low Energy health devices. 
We are working with the 5.8 version of the library, kernel version 3.12.9,
bluetoothctl, and gatttool when we encountered a possible error.
We expected on the reconnection of two bonded devices, one of which had
stored measurements, that data would transfer. When running gatt tool in
medium security the first measurement to be indicated was lost.
First we used Bluetooth control to pair with the simulated agent device (a
thermometer). Then we disconnected with bluetoothctl and connected with
gatttool in order to write to the C3D (client characteristic configuration
descriptors). After setting the C3D to indicate, we transferred a
measurement successfully.  Up until this point we saw no unexpected
difference in behavior between low and medium security on the gatttool.
However upon attempting to reconnect to the simulated agent device with
medium security two unexpected behaviors occurred. First, and more
immediately apparent was that the simulated agent did not receive a
confirmation of the indication. A slightly closer look using the hcidump,
trying to find what had happened, showed that the indication had arrived at
the hci layer but was not received at events_handler.  While the indication
is sent very swiftly upon the reconnection of the devices we understand this
to be the manner in which low energy devices are supposed to behave given
stored measurements and a bonded device.
Records of hcidumps are attached.

Caleb Reinhold


^ permalink raw reply

* Re: [PATCH 01/11] android/unit: Fix checking for expected termination
From: Szymon Janc @ 2014-02-04 20:37 UTC (permalink / raw)
  To: Jakub Tyszkowski; +Cc: linux-bluetooth
In-Reply-To: <1391524749-2518-1-git-send-email-jakub.tyszkowski@tieto.com>

Hi Jakub,

On Tuesday 04 February 2014 15:38:59 Jakub Tyszkowski wrote:
> This fix makes sure that when signalled termination is expected,
> it actually happens. If IPC termination is expected no response will be
> sent, so cmd_watch will never be executed. But if it is executed when
> expecting termination, its a failure.
> ---
>  android/test-ipc.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/android/test-ipc.c b/android/test-ipc.c
> index 8af5739..d0f3f6b 100644
> --- a/android/test-ipc.c
> +++ b/android/test-ipc.c
> @@ -82,6 +82,8 @@ static gboolean cmd_watch(GIOChannel *io, GIOCondition
> cond, uint8_t buf[128];
>  	int sk;
> 
> +	g_assert(test_data->expected_signal == 0);
> +
>  	if (cond & (G_IO_HUP | G_IO_ERR | G_IO_NVAL)) {
>  		g_assert(FALSE);
>  		return FALSE;

All patches are now upstream, thanks.

-- 
Szymon K. Janc
szymon.janc@gmail.com

^ permalink raw reply

* Re: [RFC v7 08/11] Bluetooth: Temporarily stop background scanning on discovery
From: Andre Guedes @ 2014-02-04 18:33 UTC (permalink / raw)
  To: Marcel Holtmann; +Cc: BlueZ development
In-Reply-To: <9BB5F5F9-6828-491B-B918-B0909BCA2408@holtmann.org>


Hi Marcel,

On Mon, 2014-02-03 at 20:25 -0800, Marcel Holtmann wrote:
> Hi Andre,
> 
> > If the user sends a mgmt start discovery command while the background
> > scanning is running, we should temporarily stop it. Once the discovery
> > finishes, we start the background scanning again.
> > 
> > Signed-off-by: Andre Guedes <andre.guedes@openbossa.org>
> > ---
> > net/bluetooth/hci_core.c |  2 ++
> > net/bluetooth/mgmt.c     | 12 ++++++++----
> > 2 files changed, 10 insertions(+), 4 deletions(-)
> > 
> > diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
> > index 388a453..222bd07 100644
> > --- a/net/bluetooth/hci_core.c
> > +++ b/net/bluetooth/hci_core.c
> > @@ -1609,6 +1609,8 @@ void hci_discovery_set_state(struct hci_dev *hdev, int state)
> > 
> > 	switch (state) {
> > 	case DISCOVERY_STOPPED:
> > +		hci_update_background_scan(hdev);
> > +
> > 		if (hdev->discovery.state != DISCOVERY_STARTING)
> > 			mgmt_discovering(hdev, 0);
> > 		break;
> > diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
> > index ce7ef33..83af8de 100644
> > --- a/net/bluetooth/mgmt.c
> > +++ b/net/bluetooth/mgmt.c
> > @@ -3319,11 +3319,15 @@ static int start_discovery(struct sock *sk, struct hci_dev *hdev,
> > 			goto failed;
> > 		}
> > 
> > +		/* If controller is scanning, it means the background scanning
> > +		 * is running. Thus, we should temporarily stop it in order to
> > +		 * set the discovery scanning parameters.
> > +		 */
> > 		if (test_bit(HCI_LE_SCAN, &hdev->dev_flags)) {
> > -			err = cmd_status(sk, hdev->id, MGMT_OP_START_DISCOVERY,
> > -					 MGMT_STATUS_BUSY);
> > -			mgmt_pending_remove(cmd);
> > -			goto failed;
> > +			memset(&enable_cp, 0, sizeof(enable_cp));
> > +			enable_cp.enable = LE_SCAN_DISABLE;
> > +			hci_req_add(&req, HCI_OP_LE_SET_SCAN_ENABLE,
> > +				    sizeof(enable_cp), &enable_cp);
> > 		}
> 
> is the start_discovery protected enough by itself so that we do not accidentally stop some discovery that got triggered which is actually not a background scan.

A few lines above (the diff doesn't show it), we check the discovery
state, ensuring the discovery is not running at this point.

BR,

Andre

^ permalink raw reply

* Re: [RFC v7 07/11] Bluetooth: Re-enable background scan in case of error
From: Andre Guedes @ 2014-02-04 18:32 UTC (permalink / raw)
  To: Marcel Holtmann; +Cc: BlueZ development
In-Reply-To: <D3ABE58A-C3B4-4BF1-8C7B-BE63ECED7C89@holtmann.org>


Hi Marcel,

On Mon, 2014-02-03 at 20:10 -0800, Marcel Holtmann wrote:
> Hi Andre,
> 
> > Since we temporarily stop the background scanning in favor of
> > connection, we should re-enable it in case something goes wrong
> > with connection establishment. So this patch adds a hci_update_
> > background_scan() call in fail_conn_attempt() and hci_le_conn_
> > complete_evt() error flow.
> > 
> > Signed-off-by: Andre Guedes <andre.guedes@openbossa.org>
> > ---
> > net/bluetooth/hci_conn.c  | 2 ++
> > net/bluetooth/hci_event.c | 1 +
> > 2 files changed, 3 insertions(+)
> > 
> > diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
> > index 127465f..2ef29c7 100644
> > --- a/net/bluetooth/hci_conn.c
> > +++ b/net/bluetooth/hci_conn.c
> > @@ -527,6 +527,8 @@ static void le_conn_failed(struct hci_conn *conn, u8 status)
> > 	hci_proto_connect_cfm(conn, status);
> > 
> > 	hci_conn_del(conn);
> > +
> > +	hci_update_background_scan(hdev);
> > }
> > 
> > static void create_le_conn_complete(struct hci_dev *hdev, u8 status)
> > diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
> > index ef95030..8de51b1 100644
> > --- a/net/bluetooth/hci_event.c
> > +++ b/net/bluetooth/hci_event.c
> > @@ -3606,6 +3606,7 @@ static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
> > 		hci_proto_connect_cfm(conn, ev->status);
> > 		conn->state = BT_CLOSED;
> > 		hci_conn_del(conn);
> > +		hci_update_background_scan(hdev);
> > 		goto unlock;
> 
> please fold this patch into the one that does the disabling.

I'll squash this patch into 06/11.

- Andre

^ permalink raw reply

* Re: [RFC v7 03/11] Bluetooth: Stop scanning on LE connection
From: Andre Guedes @ 2014-02-04 18:32 UTC (permalink / raw)
  To: Marcel Holtmann; +Cc: BlueZ development
In-Reply-To: <629D5403-D2BD-4DCE-B243-41CE971DE914@holtmann.org>


Hi Marcel,

On Mon, 2014-02-03 at 20:08 -0800, Marcel Holtmann wrote:
> Hi Andrei,
> 
> > Some LE controllers don't support scanning and creating a connection
> > at the same time. So we should always stop scanning in order to
> > establish the connection.
> > 
> > Since we may prematurely stop the discovery procedure in favor of
> > the connection establishment, we should also cancel hdev->le_scan_
> > disable delayed work and set the discovery state to DISCOVERY_STOPPED.
> > 
> > This change does a small improvement since it is not mandatory the
> > user stops scanning before connecting anymore. Moreover, this change
> > is required by upcoming LE auto connection mechanism in order to work
> > properly with controllers that don't support background scanning and
> > connection establishment at the same time.
> > 
> > In future, we might want to do a small optimization by checking if
> > controller is able to scan and connect at the same time. For now,
> > we want the simplest approach so we always stop scanning (even if
> > the controller is able to carry out both operations).
> > 
> > Signed-off-by: Andre Guedes <andre.guedes@openbossa.org>
> > ---
> > include/net/bluetooth/hci.h |  1 +
> > net/bluetooth/hci_conn.c    | 84 +++++++++++++++++++++++++++++++++++++++++++--
> > 2 files changed, 83 insertions(+), 2 deletions(-)
> > 
> > diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
> > index 352d3d7..a0d5262 100644
> > --- a/include/net/bluetooth/hci.h
> > +++ b/include/net/bluetooth/hci.h
> > @@ -352,6 +352,7 @@ enum {
> > 
> > /* ---- HCI Error Codes ---- */
> > #define HCI_ERROR_AUTH_FAILURE		0x05
> > +#define HCI_ERROR_MEMORY_EXCEEDED	0x07
> > #define HCI_ERROR_CONNECTION_TIMEOUT	0x08
> > #define HCI_ERROR_REJ_BAD_ADDR		0x0f
> > #define HCI_ERROR_REMOTE_USER_TERM	0x13
> > diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
> > index 6797292..63c1e4f 100644
> > --- a/net/bluetooth/hci_conn.c
> > +++ b/net/bluetooth/hci_conn.c
> > @@ -583,11 +583,71 @@ static int hci_create_le_conn(struct hci_conn *conn)
> > 	return 0;
> > }
> > 
> > +static void create_le_conn_req(struct hci_request *req, struct hci_conn *conn)
> > +{
> > +	struct hci_cp_le_create_conn cp;
> > +	struct hci_dev *hdev = conn->hdev;
> > +
> > +	memset(&cp, 0, sizeof(cp));
> > +	cp.scan_interval = cpu_to_le16(hdev->le_scan_interval);
> > +	cp.scan_window = cpu_to_le16(hdev->le_scan_window);
> > +	bacpy(&cp.peer_addr, &conn->dst);
> > +	cp.peer_addr_type = conn->dst_type;
> > +	cp.own_address_type = conn->src_type;
> > +	cp.conn_interval_min = cpu_to_le16(conn->le_conn_min_interval);
> > +	cp.conn_interval_max = cpu_to_le16(conn->le_conn_max_interval);
> > +	cp.supervision_timeout = __constant_cpu_to_le16(0x002a);
> > +	cp.min_ce_len = __constant_cpu_to_le16(0x0000);
> > +	cp.max_ce_len = __constant_cpu_to_le16(0x0000);
> > +
> > +	hci_req_add(req, HCI_OP_LE_CREATE_CONN, sizeof(cp), &cp);
> > +}
> > +
> > +static void stop_scan_complete(struct hci_dev *hdev, u8 status)
> > +{
> > +	struct hci_request req;
> > +	struct hci_conn *conn;
> > +	int err;
> > +
> > +	conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
> > +	if (!conn)
> > +		return;
> > +
> > +	if (status) {
> > +		BT_DBG("HCI request failed to stop scanning: status 0x%2.2x",
> > +		       status);
> > +
> > +		hci_dev_lock(hdev);
> > +		le_conn_failed(conn, status);
> > +		hci_dev_unlock(hdev);
> > +		return;
> > +	}
> > +
> > +	/* Since we may have prematurely stopped discovery procedure, we should
> > +	 * update discovery state.
> > +	 */
> > +	cancel_delayed_work(&hdev->le_scan_disable);
> > +	hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
> > +
> > +	hci_req_init(&req, hdev);
> > +
> > +	create_le_conn_req(&req, conn);
> > +
> > +	err = hci_req_run(&req, create_le_conn_complete);
> > +	if (err) {
> > +		hci_dev_lock(hdev);
> > +		le_conn_failed(conn, HCI_ERROR_MEMORY_EXCEEDED);
> > +		hci_dev_unlock(hdev);
> > +		return;
> > +	}
> > +}
> > +
> > static struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
> > 				    u8 dst_type, u8 sec_level, u8 auth_type)
> > {
> > 	struct hci_conn_params *params;
> > 	struct hci_conn *conn;
> > +	struct hci_request req;
> > 	int err;
> > 
> > 	if (test_bit(HCI_ADVERTISING, &hdev->flags))
> > @@ -643,9 +703,29 @@ static struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
> > 		conn->le_conn_max_interval = hdev->le_conn_max_interval;
> > 	}
> > 
> > -	err = hci_create_le_conn(conn);
> > -	if (err)
> > +	hci_req_init(&req, hdev);
> > +
> > +	/* If controller is scanning, we stop it since some controllers are
> > +	 * not able to scan and connect at the same time.
> > +	 */
> > +	if (test_bit(HCI_LE_SCAN, &hdev->dev_flags)) {
> > +		struct hci_cp_le_set_scan_enable cp;
> > +
> > +		memset(&cp, 0, sizeof(cp));
> > +		cp.enable = LE_SCAN_DISABLE;
> > +		hci_req_add(&req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
> > +
> > +		err = hci_req_run(&req, stop_scan_complete);
> > +	} else {
> > +		create_le_conn_req(&req, conn);
> > +
> > +		err = hci_req_run(&req, create_le_conn_complete);
> > +	}
> 
> so I wonder why we not just add the disabling of the scan to the request right here. Our request queue will always fail on the first request and then do not execute the other ones. Especially when you have to send two requests this kind of request queue behavior is pretty nice.

That approach was implemented in some previous version of this patch
set. However, after some discussions with Johan (see "[RFC v4 05/12]
Bluetooth: Stop scanning on LE connection"), we realized that approach
is not good enough. Moreover, that approach makes harder to handle
discovery state properly in case of HCI command error (e.g. disable scan
command succeed but create LE connection command fails).

> I also think that this is currently a bit racy in error handling path. So you might want to check this in all cases. One other thing to consider is might be introducing helper for adding certain commands like disable LE scan if they are used more than once.

I rechecked the error handling paths and didn't find any obvious race
condition. Could you point me any suspicion so I can investigate?

Regarding the disable LE scan request helper, I think it makes sense.
I'll do this refactoring and add the patch to this patch set.

Regards,

Andre

^ permalink raw reply

* [PATCH BlueZ v6 18/18] bluetooth.conf: Add ObjectManager interface
From: Claudio Takahasi @ 2014-02-04 17:53 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: claudio.takahasi
In-Reply-To: <1391536429-8345-1-git-send-email-claudio.takahasi@openbossa.org>

---
 src/bluetooth.conf | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/bluetooth.conf b/src/bluetooth.conf
index 0495200..ad8891a 100644
--- a/src/bluetooth.conf
+++ b/src/bluetooth.conf
@@ -18,6 +18,7 @@
     <allow send_interface="org.bluez.Profile1"/>
     <allow send_interface="org.bluez.HeartRateWatcher1"/>
     <allow send_interface="org.bluez.CyclingSpeedWatcher1"/>
+    <allow send_interface="org.freedesktop.DBus.ObjectManager"/>
   </policy>
 
   <policy at_console="true">
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH BlueZ v6 17/18] gatttool: Add unix socket support for interactive mode
From: Claudio Takahasi @ 2014-02-04 17:53 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: claudio.takahasi
In-Reply-To: <1391536429-8345-1-git-send-email-claudio.takahasi@openbossa.org>

This patch allows running GATT operations over unix socket on
interactive mode.
---
 attrib/interactive.c | 19 +++++++++++--------
 1 file changed, 11 insertions(+), 8 deletions(-)

diff --git a/attrib/interactive.c b/attrib/interactive.c
index 70c091c..67e060e 100644
--- a/attrib/interactive.c
+++ b/attrib/interactive.c
@@ -84,7 +84,7 @@ static char *get_prompt(void)
 	if (opt_dst)
 		g_string_append_printf(prompt, "[%17s]", opt_dst);
 	else
-		g_string_append_printf(prompt, "[%17s]", "");
+		g_string_append_printf(prompt, "[LOCAL]");
 
 	if (conn_state == STATE_CONNECTED)
 		g_string_append(prompt, COLOR_OFF);
@@ -405,15 +405,18 @@ static void cmd_connect(int argcp, char **argvp)
 			opt_dst_type = g_strdup("public");
 	}
 
-	if (opt_dst == NULL) {
-		error("Remote Bluetooth address required\n");
-		return;
+	if (opt_dst) {
+
+		rl_printf("Attempting to connect to %s\n", opt_dst);
+		set_state(STATE_CONNECTING);
+		iochannel = gatt_connect(opt_src, opt_dst, opt_dst_type,
+					opt_sec_level, opt_psm, opt_mtu,
+					connect_cb, &gerr);
+	} else {
+		rl_printf("Local connection\n");
+		iochannel = unix_connect(connect_cb, &gerr);
 	}
 
-	rl_printf("Attempting to connect to %s\n", opt_dst);
-	set_state(STATE_CONNECTING);
-	iochannel = gatt_connect(opt_src, opt_dst, opt_dst_type, opt_sec_level,
-					opt_psm, opt_mtu, connect_cb, &gerr);
 	if (iochannel == NULL) {
 		set_state(STATE_DISCONNECTED);
 		error("%s\n", gerr->message);
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH BlueZ v6 16/18] gatttool: Add unix socket connect
From: Claudio Takahasi @ 2014-02-04 17:53 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: claudio.takahasi
In-Reply-To: <1391536429-8345-1-git-send-email-claudio.takahasi@openbossa.org>

This patch adds the initial support for GATT procedures over unix
socket transport on command line mode (one-shot command). Temporary
solution to allow local GATT procedures testing.
---
 attrib/gatttool.c | 27 ++++++++++++++++++++-------
 attrib/gatttool.h |  1 +
 attrib/utils.c    | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 75 insertions(+), 7 deletions(-)

diff --git a/attrib/gatttool.c b/attrib/gatttool.c
index 9f2ead9..cf106de 100644
--- a/attrib/gatttool.c
+++ b/attrib/gatttool.c
@@ -29,7 +29,6 @@
 #include <errno.h>
 #include <glib.h>
 #include <stdlib.h>
-#include <unistd.h>
 
 #include <bluetooth/bluetooth.h>
 #include <bluetooth/hci.h>
@@ -53,6 +52,7 @@ static int opt_end = 0xffff;
 static int opt_handle = -1;
 static int opt_mtu = 0;
 static int opt_psm = 0;
+static gboolean opt_local = FALSE;
 static gboolean opt_primary = FALSE;
 static gboolean opt_characteristics = FALSE;
 static gboolean opt_char_read = FALSE;
@@ -511,6 +511,8 @@ static GOptionEntry options[] = {
 		"Specify local adapter interface", "hciX" },
 	{ "device", 'b', 0, G_OPTION_ARG_STRING, &opt_dst,
 		"Specify remote Bluetooth address", "MAC" },
+	{ "local", 'L', 0, G_OPTION_ARG_NONE, &opt_local,
+		"Use unix socket transport (local communication)", NULL },
 	{ "addr-type", 't', 0, G_OPTION_ARG_STRING, &opt_dst_type,
 		"Set LE address type. Default: public", "[public | random]"},
 	{ "mtu", 'm', 0, G_OPTION_ARG_INT, &opt_mtu,
@@ -563,6 +565,11 @@ int main(int argc, char *argv[])
 		g_clear_error(&gerr);
 	}
 
+	if (opt_local) {
+		opt_src = NULL;
+		opt_dst = NULL;
+	}
+
 	if (opt_interactive) {
 		interactive(opt_src, opt_dst, opt_dst_type, opt_psm);
 		goto done;
@@ -588,14 +595,20 @@ int main(int argc, char *argv[])
 		goto done;
 	}
 
-	if (opt_dst == NULL) {
-		g_print("Remote Bluetooth address required\n");
-		got_error = TRUE;
-		goto done;
+	if (opt_local)
+		chan = unix_connect(connect_cb, &gerr);
+	else {
+		if (opt_dst == NULL) {
+			g_print("Remote Bluetooth address required\n");
+			got_error = TRUE;
+			goto done;
+		}
+
+		chan = gatt_connect(opt_src, opt_dst, opt_dst_type,
+					opt_sec_level, opt_psm, opt_mtu,
+					connect_cb, &gerr);
 	}
 
-	chan = gatt_connect(opt_src, opt_dst, opt_dst_type, opt_sec_level,
-					opt_psm, opt_mtu, connect_cb, &gerr);
 	if (chan == NULL) {
 		g_printerr("%s\n", gerr->message);
 		g_clear_error(&gerr);
diff --git a/attrib/gatttool.h b/attrib/gatttool.h
index 8f0913c..be8e236 100644
--- a/attrib/gatttool.h
+++ b/attrib/gatttool.h
@@ -27,4 +27,5 @@ GIOChannel *gatt_connect(const char *src, const char *dst,
 			const char *dst_type, const char *sec_level,
 			int psm, int mtu, BtIOConnect connect_cb,
 			GError **gerr);
+GIOChannel *unix_connect(BtIOConnect connect_cb, GError **gerr);
 size_t gatt_attr_data_from_string(const char *str, uint8_t **data);
diff --git a/attrib/utils.c b/attrib/utils.c
index 17f02be..7d2966f 100644
--- a/attrib/utils.c
+++ b/attrib/utils.c
@@ -25,7 +25,12 @@
 #include "config.h"
 #endif
 
+#include <errno.h>
 #include <stdlib.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+
 #include <glib.h>
 
 #include <bluetooth/bluetooth.h>
@@ -101,6 +106,55 @@ GIOChannel *gatt_connect(const char *src, const char *dst,
 	return chan;
 }
 
+static gboolean unix_connect_cb(GIOChannel *io, GIOCondition cond,
+							gpointer user_data)
+{
+	BtIOConnect connect_cb = user_data;
+	GError *gerr;
+
+	if (cond & (G_IO_HUP | G_IO_ERR | G_IO_NVAL)) {
+		gerr = g_error_new_literal(G_IO_CHANNEL_ERROR,
+						G_IO_CHANNEL_ERROR_FAILED,
+						"connection attempt failed");
+		connect_cb(io, gerr, user_data);
+		g_clear_error(&gerr);
+	} else {
+		connect_cb(io, NULL, user_data);
+	}
+
+	return FALSE;
+}
+
+GIOChannel *unix_connect(BtIOConnect connect_cb, GError **gerr)
+{
+	GIOChannel *io;
+	struct sockaddr_un uaddr  = {
+		.sun_family	= AF_UNIX,
+		.sun_path	= "\0/bluetooth/unix_att",
+	};
+	int sk;
+
+	sk = socket(AF_UNIX, SOCK_SEQPACKET | SOCK_CLOEXEC , 0);
+	if (sk < 0) {
+		g_set_error_literal(gerr, G_IO_CHANNEL_ERROR,
+				G_IO_CHANNEL_ERROR_FAILED, strerror(errno));
+		return NULL;
+	}
+
+	if (connect(sk, (struct sockaddr *) &uaddr, sizeof(uaddr)) < 0) {
+		g_set_error_literal(gerr, G_IO_CHANNEL_ERROR,
+				G_IO_CHANNEL_ERROR_FAILED, strerror(errno));
+		close(sk);
+		return NULL;
+	}
+
+	io = g_io_channel_unix_new(sk);
+	g_io_add_watch(io, G_IO_OUT | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
+						unix_connect_cb, connect_cb);
+
+	return io;
+}
+
 size_t gatt_attr_data_from_string(const char *str, uint8_t **data)
 {
 	char tmp[3];
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH BlueZ v6 15/18] test: Add registering external service
From: Claudio Takahasi @ 2014-02-04 17:53 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: claudio.takahasi
In-Reply-To: <1391536429-8345-1-git-send-email-claudio.takahasi@openbossa.org>

This patch extends gatt-service to call RegisterService() when org.bluez
service gets connected to the system bus.
---
 test/gatt-service.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 67 insertions(+)

diff --git a/test/gatt-service.c b/test/gatt-service.c
index 4059336..b656ef3 100644
--- a/test/gatt-service.c
+++ b/test/gatt-service.c
@@ -35,6 +35,7 @@
 #include <dbus/dbus.h>
 #include <gdbus/gdbus.h>
 
+#define GATT_MGR_IFACE			"org.bluez.GattManager1"
 #define SERVICE_IFACE			"org.bluez.GattService1"
 
 /* Immediate Alert Service UUID */
@@ -100,6 +101,65 @@ static void create_services(DBusConnection *conn)
 	printf("Registered service: %s\n", service_path);
 }
 
+static void register_external_service_reply(DBusPendingCall *call,
+							void *user_data)
+{
+	DBusMessage *reply = dbus_pending_call_steal_reply(call);
+	DBusError derr;
+
+	dbus_error_init(&derr);
+	dbus_set_error_from_message(&derr, reply);
+
+	if (dbus_error_is_set(&derr))
+		printf("RegisterService: %s\n", derr.message);
+	else
+		printf("RegisterService: OK\n");
+
+	dbus_message_unref(reply);
+	dbus_error_free(&derr);
+}
+
+static void register_external_service(gpointer a, gpointer b)
+{
+	DBusConnection *conn = b;
+	const char *path = a;
+	DBusMessage *msg;
+	DBusPendingCall *call;
+	DBusMessageIter iter, dict;
+
+	msg = dbus_message_new_method_call("org.bluez", "/org/bluez",
+					GATT_MGR_IFACE, "RegisterService");
+	if (msg == NULL) {
+		printf("Couldn't allocate D-Bus message\n");
+		return;
+	}
+
+	dbus_message_iter_init_append(msg, &iter);
+
+	dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH, &path);
+
+	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "{sv}", &dict);
+
+	/* TODO: Add options dictionary */
+
+	dbus_message_iter_close_container(&iter, &dict);
+
+	if (g_dbus_send_message_with_reply(conn, msg, &call, -1) == FALSE) {
+		dbus_message_unref(msg);
+		return;
+	}
+
+	dbus_pending_call_set_notify(call, register_external_service_reply,
+								NULL, NULL);
+
+	dbus_pending_call_unref(call);
+}
+
+static void connect_handler(DBusConnection *conn, void *user_data)
+{
+	g_slist_foreach(services, register_external_service, conn);
+}
+
 static gboolean signal_handler(GIOChannel *channel, GIOCondition cond,
 							gpointer user_data)
 {
@@ -171,6 +231,7 @@ static guint setup_signalfd(void)
 
 int main(int argc, char *argv[])
 {
+	GDBusClient *client;
 	DBusConnection *dbus_conn;
 	guint signal;
 
@@ -189,8 +250,14 @@ int main(int argc, char *argv[])
 
 	create_services(dbus_conn);
 
+	client = g_dbus_client_new(dbus_conn, "org.bluez", "/org/bluez");
+
+	g_dbus_client_set_connect_watch(client, connect_handler, NULL);
+
 	g_main_loop_run(main_loop);
 
+	g_dbus_client_unref(client);
+
 	g_source_remove(signal);
 
 	g_slist_free_full(services, g_free);
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH BlueZ v6 14/18] test: Add signal handling for gatt-service
From: Claudio Takahasi @ 2014-02-04 17:53 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: claudio.takahasi
In-Reply-To: <1391536429-8345-1-git-send-email-claudio.takahasi@openbossa.org>

This patch implements signal handling to run cleanup tasks before
exiting.
---
 test/gatt-service.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 79 insertions(+)

diff --git a/test/gatt-service.c b/test/gatt-service.c
index 769fd37..4059336 100644
--- a/test/gatt-service.c
+++ b/test/gatt-service.c
@@ -27,6 +27,9 @@
 
 #include <errno.h>
 #include <stdio.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <sys/signalfd.h>
 
 #include <glib.h>
 #include <dbus/dbus.h>
@@ -97,9 +100,83 @@ static void create_services(DBusConnection *conn)
 	printf("Registered service: %s\n", service_path);
 }
 
+static gboolean signal_handler(GIOChannel *channel, GIOCondition cond,
+							gpointer user_data)
+{
+	static bool __terminated = false;
+	struct signalfd_siginfo si;
+	ssize_t result;
+	int fd;
+
+	if (cond & (G_IO_NVAL | G_IO_ERR | G_IO_HUP))
+		return FALSE;
+
+	fd = g_io_channel_unix_get_fd(channel);
+
+	result = read(fd, &si, sizeof(si));
+	if (result != sizeof(si))
+		return FALSE;
+
+	switch (si.ssi_signo) {
+	case SIGINT:
+	case SIGTERM:
+		if (!__terminated) {
+			printf("Terminating\n");
+			g_main_loop_quit(main_loop);
+		}
+
+		__terminated = true;
+		break;
+	}
+
+	return TRUE;
+}
+
+static guint setup_signalfd(void)
+{
+	GIOChannel *channel;
+	guint source;
+	sigset_t mask;
+	int fd;
+
+	sigemptyset(&mask);
+	sigaddset(&mask, SIGINT);
+	sigaddset(&mask, SIGTERM);
+
+	if (sigprocmask(SIG_BLOCK, &mask, NULL) < 0) {
+		perror("Failed to set signal mask");
+		return 0;
+	}
+
+	fd = signalfd(-1, &mask, 0);
+	if (fd < 0) {
+		perror("Failed to create signal descriptor");
+		return 0;
+	}
+
+	channel = g_io_channel_unix_new(fd);
+
+	g_io_channel_set_close_on_unref(channel, TRUE);
+	g_io_channel_set_encoding(channel, NULL, NULL);
+	g_io_channel_set_buffered(channel, FALSE);
+
+	source = g_io_add_watch(channel,
+				G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
+				signal_handler, NULL);
+
+	g_io_channel_unref(channel);
+
+	return source;
+}
+
 int main(int argc, char *argv[])
 {
 	DBusConnection *dbus_conn;
+	guint signal;
+
+	signal = setup_signalfd();
+	if (signal == 0)
+		return -errno;
 
 	dbus_conn = g_dbus_setup_bus(DBUS_BUS_SYSTEM, NULL, NULL);
 
@@ -114,6 +191,8 @@ int main(int argc, char *argv[])
 
 	g_main_loop_run(main_loop);
 
+	g_source_remove(signal);
+
 	g_slist_free_full(services, g_free);
 	dbus_connection_unref(dbus_conn);
 
-- 
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