Linux bluetooth development
 help / color / mirror / Atom feed
* Re: [PATCH] android/daemon: Save adapter name on complete event
From: Marcel Holtmann @ 2013-11-05 12:28 UTC (permalink / raw)
  To: Andrei Emeltchenko; +Cc: linux-bluetooth@vger.kernel.org development
In-Reply-To: <1383646128-8077-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

Hi Andrei,

> Saving adapter name was missing from set name complete event.
> Refactor code to function and reuse it in both places where
> name is changed.
> ---
> android/adapter.c |   21 ++++++++++++++-------
> 1 file changed, 14 insertions(+), 7 deletions(-)
> 
> diff --git a/android/adapter.c b/android/adapter.c
> index b6f6096..6b0dc8b 100644
> --- a/android/adapter.c
> +++ b/android/adapter.c
> @@ -88,6 +88,17 @@ static void adapter_name_changed(const uint8_t *name)
> 			HAL_EV_ADAPTER_PROPS_CHANGED, sizeof(buf), ev, -1);
> }
> 
> +static void adapter_set_name(const uint8_t *name)
> +{
> +	if (!g_strcmp0(adapter->name, (const char *) name))
> +		return;
> +
> +	DBG("Cnage name: %s -> %s", adapter->name, name);
> +
> +	g_free(adapter->name);
> +	adapter->name = g_strdup((const char *) name);
> +}
> +
> static void mgmt_local_name_changed_event(uint16_t index, uint16_t length,
> 					const void *param, void *user_data)
> {
> @@ -98,13 +109,7 @@ static void mgmt_local_name_changed_event(uint16_t index, uint16_t length,
> 		return;
> 	}
> 
> -	if (!g_strcmp0(adapter->name, (const char *) rp->name))
> -		return;
> -
> -	DBG("name: %s", rp->name);
> -
> -	g_free(adapter->name);
> -	adapter->name = g_strdup((const char *) rp->name);
> +	adapter_set_name(rp->name);
> 
> 	adapter_name_changed(rp->name);
> }
> @@ -879,6 +884,8 @@ static void set_adapter_name_complete(uint8_t status, uint16_t length,
> 		return;
> 	}
> 
> +	adapter_set_name(rp->name);
> +
> 	adapter_name_changed(rp->name);

can we feed adapter_set_name and adapter_name_change into a single function. Especially since this is not public API and will never be, please make sure consolidate these things properly. Copies from src/adapter.c are pointless since it does not have to handle any special cases like external hostnamed daemon or plugins.

With most of these function, we need to make to store the value and send out a notification. We never do anything else. So lets keep this simple. No need to spaghetti code.

Regards

Marcel


^ permalink raw reply

* Re: [PATCH] Bluetooth: Fix rejecting SMP security request in slave role
From: Marcel Holtmann @ 2013-11-05 12:33 UTC (permalink / raw)
  To: Johan Hedberg; +Cc: linux-bluetooth@vger.kernel.org development
In-Reply-To: <1383643839-2788-1-git-send-email-johan.hedberg@gmail.com>

Hi Johan,

> The SMP security request is for a slave role device to request the
> master role device to initiate a pairing request. If we receive this
> command while we're in the slave role we should reject it appropriately.
> 
> Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
> ---
> net/bluetooth/smp.c | 3 +++
> 1 file changed, 3 insertions(+)

patch has been applied to bluetooth-next tree.

Regards

Marcel


^ permalink raw reply

* Re: [PATCH] android/client: Fix build for android 4.3
From: Johan Hedberg @ 2013-11-05 12:56 UTC (permalink / raw)
  To: Jerzy Kasenberg; +Cc: linux-bluetooth
In-Reply-To: <1383652121-4121-1-git-send-email-jerzy.kasenberg@tieto.com>

Hi Jerzy,

On Tue, Nov 05, 2013, Jerzy Kasenberg wrote:
> Chagnes in HAL interface from 4.3 to 4.4 result in build failure:
> 
> target thumb C: haltest <=
>     external/bluetooth/bluez/android/client/if-gatt.c
> external/bluetooth/bluez/android/client/if-gatt.c:225:1:
>     error: unknown type name 'btgatt_gatt_id_t'
> 
> This patch allows to build GATT for Android 4.3 (api level 18).
> ---
> 
> I sent this patch to the mailing list primarily to allow people
> who work on android 4.3 to be able to build GATT.
> 
>  android/client/if-gatt.c |   27 +++++++++++++++++++++------
>  1 file changed, 21 insertions(+), 6 deletions(-)

Applied. Thanks.

Johan

^ permalink raw reply

* Re: [PATCH_v3 01/04] android/hid: Implement hid get protocol in daemon
From: Johan Hedberg @ 2013-11-05 13:10 UTC (permalink / raw)
  To: Ravi kumar Veeramally; +Cc: linux-bluetooth
In-Reply-To: <1383654126-19237-1-git-send-email-ravikumar.veeramally@linux.intel.com>

Hi Ravi,

On Tue, Nov 05, 2013, Ravi kumar Veeramally wrote:
> +static gboolean ctrl_io_watch_cb(GIOChannel *chan, gpointer data)
> +{
> +	struct hid_device *dev = data;
> +	int fd, bread;
> +	uint8_t buf[UHID_DATA_MAX];
> +
> +	DBG("");
> +
> +	fd = g_io_channel_unix_get_fd(chan);
> +	bread = read(fd, buf, sizeof(buf));
> +	if (bread < 0) {
> +		error("read: %s(%d)", strerror(errno), -errno);
> +		return TRUE;
> +	}
> +
> +	switch (dev->last_hid_msg) {
> +	case HID_MSG_GET_PROTOCOL:
> +		bt_hid_notify_proto_mode(dev, buf, bread);
> +		break;
> +	default:
> +		DBG("unhandled hid msg type 0x%02x", dev->last_hid_msg);
> +	}

This doesn't really make sense to me. If you only set last_hid_msg when
you send a code that you do support, then why would the value of
last_hid_msg ever contain a type that you do not support? (assuming you
always add an entry to this switch statement in the same patch that you
add a corresponding write for the type).

Also, since you don't seem to be using last_hid_msg for anything else
than printing this debug message, I'm wondering is there really any
value for it? Previously (based on our IRC) discussion I understood that
it had some actual functional value that helped determine what to send
to the HAL, but now I'm not seeing it anywhere in the patch. I might
have missed it though (in which case please enlighten me :)

Johan

^ permalink raw reply

* [PATCH BlueZ] android/hid: Fix passing wrong adapter address to bt_io_listen
From: Luiz Augusto von Dentz @ 2013-11-05 13:12 UTC (permalink / raw)
  To: linux-bluetooth

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

---
 android/hid.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/android/hid.c b/android/hid.c
index c0c9aeb..8f5ba88 100644
--- a/android/hid.c
+++ b/android/hid.c
@@ -749,7 +749,7 @@ bool bt_hid_register(GIOChannel *io, const bdaddr_t *addr)
 	notification_io = g_io_channel_ref(io);
 
 	ctrl_io = bt_io_listen(connect_cb, NULL, NULL, NULL, &err,
-				BT_IO_OPT_SOURCE_BDADDR, &src,
+				BT_IO_OPT_SOURCE_BDADDR, src,
 				BT_IO_OPT_PSM, L2CAP_PSM_HIDP_CTRL,
 				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
 				BT_IO_OPT_INVALID);
@@ -760,7 +760,7 @@ bool bt_hid_register(GIOChannel *io, const bdaddr_t *addr)
 	}
 
 	intr_io = bt_io_listen(connect_cb, NULL, NULL, NULL, &err,
-				BT_IO_OPT_SOURCE_BDADDR, &src,
+				BT_IO_OPT_SOURCE_BDADDR, src,
 				BT_IO_OPT_PSM, L2CAP_PSM_HIDP_INTR,
 				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
 				BT_IO_OPT_INVALID);
-- 
1.8.3.1


^ permalink raw reply related

* Re: [PATCH_v3 02/04] android/hid: Implement hid set protocol in daemon
From: Johan Hedberg @ 2013-11-05 13:12 UTC (permalink / raw)
  To: Ravi kumar Veeramally; +Cc: linux-bluetooth
In-Reply-To: <1383654126-19237-2-git-send-email-ravikumar.veeramally@linux.intel.com>

Hi Ravi,

On Tue, Nov 05, 2013, Ravi kumar Veeramally wrote:
>  static uint8_t bt_hid_set_protocol(struct hal_cmd_hid_set_protocol *cmd,
>  								uint16_t len)
>  {
> -	DBG("Not Implemented");
> +	struct hid_device *dev;
> +	GSList *l;
> +	bdaddr_t dst;
> +	int fd;
> +	uint8_t hdr[1];

If it's just one element there's no need for an array. Just use
"uint8_t hdr;" instead.

> +	hdr[0] = HID_MSG_SET_PROTOCOL | cmd->mode;

And then here hdr = ...;

> +	fd = g_io_channel_unix_get_fd(dev->ctrl_io);
> +
> +	if (write(fd, hdr, sizeof(hdr)) < 0) {

And here &hdr, sizeof(hdr)

Johan

^ permalink raw reply

* Re: [PATCH_v3 03/04] android/hid: Implement hid get report in daemon
From: Johan Hedberg @ 2013-11-05 13:16 UTC (permalink / raw)
  To: Ravi kumar Veeramally; +Cc: linux-bluetooth
In-Reply-To: <1383654126-19237-3-git-send-email-ravikumar.veeramally@linux.intel.com>

Hi Ravi,

On Tue, Nov 05, 2013, Ravi kumar Veeramally wrote:
> +	if (!((buf[0] == (HID_MSG_DATA | HID_DATA_TYPE_INPUT)) ||
> +			(buf[0] == (HID_MSG_DATA | HID_DATA_TYPE_OUTPUT)) ||
> +			(buf[0]	== (HID_MSG_DATA | HID_DATA_TYPE_FEATURE)))) {
> +		ev = g_malloc(len);
> +		memset(ev, 0, ev_len);

Is it intentional that you allocate a different length than what you
memset to 0 here? If they should be the same just use g_malloc0, and if
not a code comment might be in order (to explain what the actual
intention is).

> +	ev = g_malloc(ev_len);
> +	memset(ev, 0, ev_len);

Here g_malloc0 makes more sense.

> +	ev->status = HAL_HID_STATUS_OK;
> +	bdaddr2android(&dev->dst, ev->bdaddr);
> +
> +	/* Report porotocol mode reply contains id after hdr, in boot
> +	 * protocol mode id doesn't exist */
> +	if (dev->boot_dev) {
> +		ev->len = len - 1;
> +		memcpy(ev->data, buf + 1, ev->len);
> +	} else {
> +		ev->len = len - 2;
> +		memcpy(ev->data, buf + 2, ev->len);
> +	}
> +
> +send:
> +	ipc_send(notification_io, HAL_SERVICE_ID_HIDHOST, HAL_EV_HID_GET_REPORT,
> +						ev_len, ev, -1);

This doesn't look right for your first allocation (you claim that the
length of ev is ev_len, but in fact you allocated len amount of bytes.

Johan

^ permalink raw reply

* [PATCHv2 0/6] Query remote services support
From: Marcin Kraglak @ 2013-11-05 13:21 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Marcin Kraglak

V2:
 - function fetch_remote__uids renamed to browse_remote_sdp
 - result of browse_remote_sdp changed to uint8_t
 - sdp_req_list name changed to browse_reqs
 - browse_reqs contains requests, not addresses

Marcin Kraglak (6):
  android: Initial implementation of get_remote_services
  android: Fetch remote device uuids after pairing
  android: Pass found uuids to remote_device_properties_cb
  android: Add supported uuids when adapter is initialized
  android: Implement class of device property callback
  android: Add support for getting adapter uuids

 android/adapter.c | 313 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 305 insertions(+), 8 deletions(-)

-- 
1.8.4.1


^ permalink raw reply

* [PATCHv2 1/6] android: Initial implementation of get_remote_services
From: Marcin Kraglak @ 2013-11-05 13:21 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Marcin Kraglak
In-Reply-To: <1383657700-22313-1-git-send-email-marcin.kraglak@tieto.com>

This patch implements method to retrieve remote device sdp records.
Caching struct is implemented for adding fetched uuids to list.
sdp_req_list will contain list of devices which are asked for records.
Function get_remote_services will check if device is on list, and will
start sdp procedure.

---
 android/adapter.c | 100 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 99 insertions(+), 1 deletion(-)

diff --git a/android/adapter.c b/android/adapter.c
index 074fc68..40fb89d 100644
--- a/android/adapter.c
+++ b/android/adapter.c
@@ -35,6 +35,10 @@
 #include "src/shared/mgmt.h"
 #include "src/glib-helper.h"
 #include "src/eir.h"
+#include "lib/sdp.h"
+#include "lib/sdp_lib.h"
+#include "lib/uuid.h"
+#include "src/sdp-client.h"
 #include "log.h"
 #include "hal-msg.h"
 #include "ipc.h"
@@ -45,6 +49,8 @@
 #define DEFAULT_IO_CAPABILITY 0x01
 
 static GIOChannel *notification_io = NULL;
+/* This list contains addresses which are asked for records */
+static GSList *browse_reqs;
 
 struct bt_adapter {
 	uint16_t index;
@@ -63,6 +69,20 @@ struct bt_adapter {
 	bool discovering;
 };
 
+struct browse_req {
+	bdaddr_t bdaddr;
+	GSList *uuids;
+	int search_uuid;
+	int reconnect_attempt;
+};
+
+static const uint16_t uuid_list[] = {
+	L2CAP_UUID,
+	PNP_INFO_SVCLASS_ID,
+	PUBLIC_BROWSE_GROUP,
+	0
+};
+
 static struct bt_adapter *adapter;
 static GSList *found_devices = NULL;
 
@@ -262,6 +282,79 @@ static void send_bond_state_change(const bdaddr_t *addr, uint8_t status,
 			HAL_EV_BOND_STATE_CHANGED, sizeof(ev), &ev, -1);
 }
 
+static void browse_req_free(struct browse_req *req)
+{
+	g_slist_free_full(req->uuids, g_free);
+	g_free(req);
+}
+
+static void update_records(struct browse_req *req, sdp_list_t *recs)
+{
+	/* TODO cache found uuids */
+}
+
+static void browse_cb(sdp_list_t *recs, int err, gpointer user_data)
+{
+	struct browse_req *req = user_data;
+	uuid_t uuid;
+
+	/* If we have a valid response and req->search_uuid == 2, then L2CAP
+	 * UUID & PNP searching was successful -- we are done */
+	if (err < 0 || req->search_uuid == 2) {
+		if (err == -ECONNRESET && req->reconnect_attempt < 1) {
+			req->search_uuid--;
+			req->reconnect_attempt++;
+		} else {
+			goto done;
+		}
+	}
+
+	update_records(req, recs);
+
+	/* Search for mandatory uuids */
+	if (uuid_list[req->search_uuid]) {
+		sdp_uuid16_create(&uuid, uuid_list[req->search_uuid++]);
+		bt_search_service(&adapter->bdaddr, &req->bdaddr, &uuid,
+						browse_cb, user_data, NULL);
+		return;
+	}
+
+done:
+	browse_reqs = g_slist_remove(browse_reqs, req);
+	browse_req_free(req);
+}
+
+static int req_cmp(gconstpointer a, gconstpointer b)
+{
+	const struct browse_req *req = a;
+	const bdaddr_t *bdaddr = b;
+
+	return bacmp(&req->bdaddr, bdaddr);
+}
+
+static uint8_t browse_remote_sdp(const bdaddr_t *addr)
+{
+	struct browse_req *req;
+	uuid_t uuid;
+
+	if (g_slist_find_custom(browse_reqs, addr, req_cmp))
+		return HAL_STATUS_DONE;
+
+	req = g_new0(struct browse_req, 1);
+	bacpy(&req->bdaddr, addr);
+	sdp_uuid16_create(&uuid, uuid_list[req->search_uuid++]);
+
+	if (bt_search_service(&adapter->bdaddr,
+			&req->bdaddr, &uuid, browse_cb, req, NULL) < 0) {
+		browse_req_free(req);
+		return false;
+	}
+
+	browse_reqs = g_slist_append(browse_reqs, req);
+
+	return HAL_STATUS_SUCCESS;
+}
+
 static void new_link_key_callback(uint16_t index, uint16_t length,
 					const void *param, void *user_data)
 {
@@ -1482,7 +1575,12 @@ static uint8_t ssp_reply(void *buf, uint16_t len)
 
 static uint8_t get_remote_services(void *buf, uint16_t len)
 {
-	return HAL_STATUS_UNSUPPORTED;
+	struct hal_cmd_get_remote_services *cmd = buf;
+	bdaddr_t addr;
+
+	android2bdaddr(&cmd->bdaddr, &addr);
+
+	return browse_remote_sdp(&addr);
 }
 
 void bt_adapter_handle_cmd(GIOChannel *io, uint8_t opcode, void *buf,
-- 
1.8.4.1


^ permalink raw reply related

* [PATCHv2 2/6] android: Fetch remote device uuids after pairing
From: Marcin Kraglak @ 2013-11-05 13:21 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Marcin Kraglak
In-Reply-To: <1383657700-22313-1-git-send-email-marcin.kraglak@tieto.com>

Android framework expects list of bonded device's uuids.
Start sdp query after setting bond state to BOND_STATE_BONBED.

---
 android/adapter.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/android/adapter.c b/android/adapter.c
index 40fb89d..cf22e5f 100644
--- a/android/adapter.c
+++ b/android/adapter.c
@@ -387,6 +387,8 @@ static void new_link_key_callback(uint16_t index, uint16_t length,
 
 	send_bond_state_change(&addr->bdaddr, HAL_STATUS_SUCCESS,
 							HAL_BOND_STATE_BONDED);
+
+	browse_remote_sdp(&addr->bdaddr);
 }
 
 static void pin_code_request_callback(uint16_t index, uint16_t length,
-- 
1.8.4.1


^ permalink raw reply related

* [PATCHv2 3/6] android: Pass found uuids to remote_device_properties_cb
From: Marcin Kraglak @ 2013-11-05 13:21 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Marcin Kraglak
In-Reply-To: <1383657700-22313-1-git-send-email-marcin.kraglak@tieto.com>

Send remote device's uuids in remote_device_properties_cb.
This patch will pack found uuids to buffer containing property
with list of uuids and send it to notification socket.
---
 android/adapter.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 81 insertions(+), 1 deletion(-)

diff --git a/android/adapter.c b/android/adapter.c
index cf22e5f..0f24cac 100644
--- a/android/adapter.c
+++ b/android/adapter.c
@@ -288,9 +288,87 @@ static void browse_req_free(struct browse_req *req)
 	g_free(req);
 }
 
+static void fill_uuids(GSList *list, void *buf)
+{
+	for (; list; list = g_slist_next(list)) {
+		memcpy(buf, list->data, sizeof(uint128_t));
+		buf += sizeof(uint128_t);
+	}
+}
+
+static void remote_uuids_callback(struct browse_req *req)
+{
+	struct hal_ev_remote_device_props *ev;
+	int len;
+
+	len = sizeof(*ev) + sizeof(struct hal_property) + (sizeof(uint128_t) *
+						g_slist_length(req->uuids));
+	ev = g_malloc(len);
+
+	ev->status = HAL_STATUS_SUCCESS;
+	bdaddr2android(&req->bdaddr, &ev->bdaddr);
+	ev->num_props = 1;
+	ev->props[0].type = HAL_PROP_DEVICE_UUIDS;
+	ev->props[0].len = sizeof(uint128_t) * g_slist_length(req->uuids);
+	fill_uuids(req->uuids, ev->props[0].val);
+
+	ipc_send(notification_io, HAL_SERVICE_ID_BLUETOOTH,
+				HAL_EV_REMOTE_DEVICE_PROPS, len, ev, -1);
+
+	g_free(ev);
+}
+
+static int uuid_128_cmp(gconstpointer a, gconstpointer b)
+{
+	return memcmp(a, b, sizeof(uint128_t));
+}
+
 static void update_records(struct browse_req *req, sdp_list_t *recs)
 {
-	/* TODO cache found uuids */
+	for (; recs; recs = recs->next) {
+		sdp_record_t *rec = (sdp_record_t *) recs->data;
+		sdp_list_t *svcclass = NULL;
+		uuid_t uuid128;
+		uuid_t *tmp;
+		uint8_t *new_uuid;
+
+		if (!rec)
+			break;
+
+		if (sdp_get_service_classes(rec, &svcclass) < 0)
+			continue;
+
+		if (!svcclass)
+			continue;
+
+		tmp = svcclass->data;
+
+		switch (tmp->type) {
+		case SDP_UUID16:
+			sdp_uuid16_to_uuid128(&uuid128, tmp);
+			break;
+		case SDP_UUID32:
+			sdp_uuid32_to_uuid128(&uuid128, tmp);
+			break;
+		case SDP_UUID128:
+			memcpy(&uuid128, tmp, sizeof(uuid_t));
+			break;
+		default:
+			continue;
+		}
+
+		new_uuid = g_malloc(16);/* size of 128 bit uuid */
+		memcpy(new_uuid, &uuid128.value.uuid128,
+				sizeof(uuid128.value.uuid128));
+
+		/* Check if uuid is already added */
+		if (g_slist_find_custom(req->uuids, new_uuid, uuid_128_cmp))
+			g_free(new_uuid);
+		else
+			req->uuids = g_slist_append(req->uuids, new_uuid);
+
+		sdp_list_free(svcclass, free);
+	}
 }
 
 static void browse_cb(sdp_list_t *recs, int err, gpointer user_data)
@@ -320,6 +398,8 @@ static void browse_cb(sdp_list_t *recs, int err, gpointer user_data)
 	}
 
 done:
+	remote_uuids_callback(req);
+
 	browse_reqs = g_slist_remove(browse_reqs, req);
 	browse_req_free(req);
 }
-- 
1.8.4.1


^ permalink raw reply related

* [PATCHv2 4/6] android: Add supported uuids when adapter is initialized
From: Marcin Kraglak @ 2013-11-05 13:21 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Marcin Kraglak
In-Reply-To: <1383657700-22313-1-git-send-email-marcin.kraglak@tieto.com>

It will set class of device with proper service hints.
We set it statically because we want to keep code simple.

---
 android/adapter.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 59 insertions(+)

diff --git a/android/adapter.c b/android/adapter.c
index 0f24cac..70b9265 100644
--- a/android/adapter.c
+++ b/android/adapter.c
@@ -52,6 +52,29 @@ static GIOChannel *notification_io = NULL;
 /* This list contains addresses which are asked for records */
 static GSList *browse_reqs;
 
+/*
+ * This is an array of supported uuids and service hints. We add them via mgmt
+ * interface when adapter is initialized. Uuids are in reverse orded.
+ */
+static const struct mgmt_cp_add_uuid supported_services[] = {
+	/* OBEX_OPP_UUID */
+	{ .uuid = { 0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80,
+			0x00, 0x10, 0x00, 0x00, 0x05, 0x11, 0x00, 0x00 },
+	.svc_hint = 0x10 },
+	/* HFP_AG_UUID */
+	{ .uuid = { 0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80,
+			0x00, 0x10, 0x00, 0x00, 0x1f, 0x11, 0x00, 0x00 },
+	.svc_hint = 0x40 },
+	/* ADVANCED_AUDIO_UUID */
+	{ .uuid = { 0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80,
+			0x00, 0x10, 0x00, 0x00, 0x0d, 0x11, 0x00, 0x00 },
+	.svc_hint = 0x08 },
+	/* PANU_UUID */
+	{ .uuid = { 0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80,
+			0x00, 0x10, 0x00, 0x00, 0x15, 0x11, 0x00, 0x00 },
+	.svc_hint = 0x02 }
+};
+
 struct bt_adapter {
 	uint16_t index;
 	struct mgmt *mgmt;
@@ -980,6 +1003,39 @@ static void load_link_keys(GSList *keys)
 	}
 }
 
+static void add_uuid_complete(uint8_t status, uint16_t length,
+				const void *param, void *user_data)
+{
+	if (status != MGMT_STATUS_SUCCESS) {
+		error("Failed to add UUID: %s (0x%02x)",
+				mgmt_errstr(status), status);
+		return;
+	}
+
+	mgmt_dev_class_changed_event(adapter->index, length, param, NULL);
+}
+
+static void add_uuids(void)
+{
+	unsigned int i;
+
+	for (i = 0; i < NELEM(supported_services); i++)
+		mgmt_send(adapter->mgmt, MGMT_OP_ADD_UUID, adapter->index,
+				sizeof(supported_services[i]),
+				&supported_services[i], add_uuid_complete,
+				NULL, NULL);
+}
+
+static void clear_uuids(void)
+{
+	struct mgmt_cp_remove_uuid cp;
+
+	memset(&cp, 0, sizeof(cp));
+
+	mgmt_send(adapter->mgmt, MGMT_OP_REMOVE_UUID, adapter->index,
+					sizeof(cp), &cp, NULL, NULL, NULL);
+}
+
 static void set_mode_complete(uint8_t status, uint16_t length,
 					const void *param, void *user_data)
 {
@@ -995,6 +1051,9 @@ static void set_mode_complete(uint8_t status, uint16_t length,
 	 * event handling functions here.
 	 */
 	new_settings_callback(adapter->index, length, param, NULL);
+
+	clear_uuids();
+	add_uuids();
 }
 
 static bool set_mode(uint16_t opcode, uint8_t mode)
-- 
1.8.4.1


^ permalink raw reply related

* [PATCHv2 5/6] android: Implement class of device property callback
From: Marcin Kraglak @ 2013-11-05 13:21 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Marcin Kraglak
In-Reply-To: <1383657700-22313-1-git-send-email-marcin.kraglak@tieto.com>

This will send adapter property with class of device
to notification socket.

---
 android/adapter.c | 32 ++++++++++++++++++++++++++++----
 1 file changed, 28 insertions(+), 4 deletions(-)

diff --git a/android/adapter.c b/android/adapter.c
index 70b9265..89db078 100644
--- a/android/adapter.c
+++ b/android/adapter.c
@@ -212,6 +212,30 @@ static void scan_mode_changed(void)
 	g_free(ev);
 }
 
+static void send_adapter_class(void)
+{
+	struct hal_ev_adapter_props_changed *ev;
+	int len;
+
+	len = sizeof(*ev) + sizeof(struct hal_property) + sizeof(uint32_t);
+
+	ev = g_malloc(len);
+
+	ev->num_props = 1;
+	ev->status = HAL_STATUS_SUCCESS;
+
+	ev->props[0].type = HAL_PROP_ADAPTER_CLASS;
+	ev->props[0].len = sizeof(uint32_t);
+	memcpy(ev->props->val, &adapter->dev_class, sizeof(uint32_t));
+
+	DBG("Adapter class %u", adapter->dev_class);
+
+	ipc_send(notification_io, HAL_SERVICE_ID_BLUETOOTH,
+				HAL_EV_ADAPTER_PROPS_CHANGED, len, ev, -1);
+
+	g_free(ev);
+}
+
 static void settings_changed(uint32_t settings)
 {
 	uint32_t changed_mask;
@@ -280,7 +304,7 @@ static void mgmt_dev_class_changed_event(uint16_t index, uint16_t length,
 
 	adapter->dev_class = dev_class;
 
-	/* TODO: Inform prop change: Class */
+	send_adapter_class();
 
 	/* TODO: Gatt attrib set*/
 }
@@ -1278,11 +1302,11 @@ static bool get_uuids(void)
 
 static bool get_class(void)
 {
-	DBG("Not implemented");
+	DBG("");
 
-	/* TODO: Add implementation */
+	send_adapter_class();
 
-	return false;
+	return true;
 }
 
 static bool get_type(void)
-- 
1.8.4.1


^ permalink raw reply related

* [PATCHv2 6/6] android: Add support for getting adapter uuids
From: Marcin Kraglak @ 2013-11-05 13:21 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Marcin Kraglak
In-Reply-To: <1383657700-22313-1-git-send-email-marcin.kraglak@tieto.com>

Implement get adapter uuids command. It will pack supported
uuids to structure and send it via notification socket

---
 android/adapter.c | 40 +++++++++++++++++++++++++++++++++++++---
 1 file changed, 37 insertions(+), 3 deletions(-)

diff --git a/android/adapter.c b/android/adapter.c
index 89db078..6ce2211 100644
--- a/android/adapter.c
+++ b/android/adapter.c
@@ -1291,13 +1291,47 @@ static bool get_name(void)
 	return true;
 }
 
+static void swap_uuid(const uint8_t *src, uint8_t *dst)
+{
+	int i;
+
+	for (i = 0; i < 16; i++)
+		dst[15 - i] = src[i];
+}
+
 static bool get_uuids(void)
 {
-	DBG("Not implemented");
+	struct hal_ev_adapter_props_changed *ev;
+	unsigned int i;
+	int len;
+	uint8_t *p;
 
-	/* TODO: Add implementation */
+	len = sizeof(*ev) + sizeof(struct hal_property) +
+			NELEM(supported_services) * sizeof(uint128_t);
 
-	return false;
+	ev = g_malloc(len);
+
+	ev->num_props = 1;
+	ev->status = HAL_STATUS_SUCCESS;
+
+	ev->props[0].type = HAL_PROP_ADAPTER_UUIDS;
+	ev->props[0].len = sizeof(uint128_t) * NELEM(supported_services);
+	p = ev->props->val;
+
+	for (i = 0; i < NELEM(supported_services); i++) {
+		/* we have to swap supported uuids
+		 * because hal expects them in reversed order
+		 * than mgmt intrface */
+		swap_uuid(supported_services[i].uuid, p);
+		p += sizeof(uint128_t);
+	}
+
+	ipc_send(notification_io, HAL_SERVICE_ID_BLUETOOTH,
+				HAL_EV_ADAPTER_PROPS_CHANGED, len, ev, -1);
+
+	g_free(ev);
+
+	return true;
 }
 
 static bool get_class(void)
-- 
1.8.4.1


^ permalink raw reply related

* Re: [PATCH BlueZ] android/hid: Fix passing wrong adapter address to bt_io_listen
From: Johan Hedberg @ 2013-11-05 13:22 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth
In-Reply-To: <1383657140-10758-1-git-send-email-luiz.dentz@gmail.com>

Hi Luiz,

On Tue, Nov 05, 2013, Luiz Augusto von Dentz wrote:
> ---
>  android/hid.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)

Applied. Thanks.

Johan

^ permalink raw reply

* [PATCH] monitor: Fallback to 80 columns terminal if not able to get real size
From: Szymon Janc @ 2013-11-05 13:22 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

This makes num_columns always return valid number of columns, which is
expected by print_packets function.

This also fix garbage prints while using btmon via adb shell.
---
 monitor/display.c | 8 ++++----
 monitor/display.h | 2 ++
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/monitor/display.c b/monitor/display.c
index b8dce1f..af4171f 100644
--- a/monitor/display.c
+++ b/monitor/display.c
@@ -58,10 +58,10 @@ int num_columns(void)
 	if (__builtin_expect(!!(cached_num_columns < 0), 0)) {
 		struct winsize ws;
 
-		if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) < 0)
-			return -1;
-
-		if (ws.ws_col > 0)
+		if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) < 0 ||
+								ws.ws_col == 0)
+			cached_num_columns = FALLBACK_TERMINAL_WIDTH;
+		else
 			cached_num_columns = ws.ws_col;
 	}
 
diff --git a/monitor/display.h b/monitor/display.h
index 6139cc2..885eb34 100644
--- a/monitor/display.h
+++ b/monitor/display.h
@@ -40,6 +40,8 @@ bool use_color(void);
 
 #define COLOR_ERROR	"\x1B[1;31m"
 
+#define FALLBACK_TERMINAL_WIDTH 80
+
 #define print_indent(indent, color1, prefix, title, color2, fmt, args...) \
 do { \
 	printf("%*c%s%s%s%s" fmt "%s\n", (indent), ' ', \
-- 
1.8.4.1


^ permalink raw reply related

* Re: [PATCH_v3 01/04] android/hid: Implement hid get protocol in daemon
From: Ravi Kumar Veeramally @ 2013-11-05 13:27 UTC (permalink / raw)
  To: linux-bluetooth, johan.hedberg@gmail.com >> Johan Hedberg
In-Reply-To: <20131105131050.GA15228@x220.p-661hnu-f1>

Hi Johan,

On 11/05/2013 03:10 PM, Johan Hedberg wrote:
> Hi Ravi,
>
> On Tue, Nov 05, 2013, Ravi kumar Veeramally wrote:
>> +static gboolean ctrl_io_watch_cb(GIOChannel *chan, gpointer data)
>> +{
>> +	struct hid_device *dev = data;
>> +	int fd, bread;
>> +	uint8_t buf[UHID_DATA_MAX];
>> +
>> +	DBG("");
>> +
>> +	fd = g_io_channel_unix_get_fd(chan);
>> +	bread = read(fd, buf, sizeof(buf));
>> +	if (bread < 0) {
>> +		error("read: %s(%d)", strerror(errno), -errno);
>> +		return TRUE;
>> +	}
>> +
>> +	switch (dev->last_hid_msg) {
>> +	case HID_MSG_GET_PROTOCOL:
>> +		bt_hid_notify_proto_mode(dev, buf, bread);
>> +		break;
>> +	default:
>> +		DBG("unhandled hid msg type 0x%02x", dev->last_hid_msg);
>> +	}
> This doesn't really make sense to me. If you only set last_hid_msg when
> you send a code that you do support, then why would the value of
> last_hid_msg ever contain a type that you do not support? (assuming you
> always add an entry to this switch statement in the same patch that you
> add a corresponding write for the type).
>
> Also, since you don't seem to be using last_hid_msg for anything else
> than printing this debug message, I'm wondering is there really any
> value for it? Previously (based on our IRC) discussion I understood that
> it had some actual functional value that helped determine what to send
> to the HAL, but now I'm not seeing it anywhere in the patch. I might
> have missed it though (in which case please enlighten me :)
  I don't know if I understand you correctly, but at the end of all patches
  it looks like this.
          switch (dev->last_hid_msg) {
         case HID_MSG_GET_PROTOCOL:
         case HID_MSG_SET_PROTOCOL:
                 bt_hid_notify_proto_mode(dev, buf, bread);
                 break;
         case HID_MSG_GET_REPORT:
                 bt_hid_notify_get_report(dev, buf, bread);
                 break;
         default:
                 DBG("unhandled hid msg type 0x%02x", dev->last_hid_msg);
         }

based on last_hid_msg switch case, it will call respective function,
default statement is for debug purpose if we miss something from hid device.

Thanks,
Ravi.

^ permalink raw reply

* Re: [PATCH_v3 02/04] android/hid: Implement hid set protocol in daemon
From: Ravi Kumar Veeramally @ 2013-11-05 13:52 UTC (permalink / raw)
  To: linux-bluetooth, Johan Hedberg
In-Reply-To: <20131105131232.GB15228@x220.p-661hnu-f1>

Hi Johan,

On 11/05/2013 03:12 PM, Johan Hedberg wrote:
> Hi Ravi,
>
> On Tue, Nov 05, 2013, Ravi kumar Veeramally wrote:
>>   static uint8_t bt_hid_set_protocol(struct hal_cmd_hid_set_protocol *cmd,
>>   								uint16_t len)
>>   {
>> -	DBG("Not Implemented");
>> +	struct hid_device *dev;
>> +	GSList *l;
>> +	bdaddr_t dst;
>> +	int fd;
>> +	uint8_t hdr[1];
> If it's just one element there's no need for an array. Just use
> "uint8_t hdr;" instead.
>
>> +	hdr[0] = HID_MSG_SET_PROTOCOL | cmd->mode;
> And then here hdr = ...;
>
>> +	fd = g_io_channel_unix_get_fd(dev->ctrl_io);
>> +
>> +	if (write(fd, hdr, sizeof(hdr)) < 0) {
> And here &hdr, sizeof(hdr)
  Ok.

Thanks,
Ravi.

^ permalink raw reply

* Re: [PATCH_v3 03/04] android/hid: Implement hid get report in daemon
From: Ravi Kumar Veeramally @ 2013-11-05 13:55 UTC (permalink / raw)
  To: linux-bluetooth, Johan Hedberg
In-Reply-To: <20131105131606.GC15228@x220.p-661hnu-f1>


On 11/05/2013 03:16 PM, Johan Hedberg wrote:
> Hi Ravi,
>
> On Tue, Nov 05, 2013, Ravi kumar Veeramally wrote:
>> +	if (!((buf[0] == (HID_MSG_DATA | HID_DATA_TYPE_INPUT)) ||
>> +			(buf[0] == (HID_MSG_DATA | HID_DATA_TYPE_OUTPUT)) ||
>> +			(buf[0]	== (HID_MSG_DATA | HID_DATA_TYPE_FEATURE)))) {
>> +		ev = g_malloc(len);
>> +		memset(ev, 0, ev_len);
> Is it intentional that you allocate a different length than what you
> memset to 0 here? If they should be the same just use g_malloc0, and if
> not a code comment might be in order (to explain what the actual
> intention is).
  Ok, type, it should be ev_len.
>> +	ev = g_malloc(ev_len);
>> +	memset(ev, 0, ev_len);
> Here g_malloc0 makes more sense.
>
>> +	ev->status = HAL_HID_STATUS_OK;
>> +	bdaddr2android(&dev->dst, ev->bdaddr);
>> +
>> +	/* Report porotocol mode reply contains id after hdr, in boot
>> +	 * protocol mode id doesn't exist */
>> +	if (dev->boot_dev) {
>> +		ev->len = len - 1;
>> +		memcpy(ev->data, buf + 1, ev->len);
>> +	} else {
>> +		ev->len = len - 2;
>> +		memcpy(ev->data, buf + 2, ev->len);
>> +	}
>> +
>> +send:
>> +	ipc_send(notification_io, HAL_SERVICE_ID_HIDHOST, HAL_EV_HID_GET_REPORT,
>> +						ev_len, ev, -1);
> This doesn't look right for your first allocation (you claim that the
> length of ev is ev_len, but in fact you allocated len amount of bytes.
  Ok. I will fix it.

Thanks,
Ravi.

^ permalink raw reply

* [PATCH 1/2] android/debug: Export print uuid function
From: Andrei Emeltchenko @ 2013-11-05 14:06 UTC (permalink / raw)
  To: linux-bluetooth

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

The function will be reused in socket HAL.
---
 android/client/textconv.c |    2 +-
 android/client/textconv.h |    1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/android/client/textconv.c b/android/client/textconv.c
index 9a2f7e6..e6f327f 100644
--- a/android/client/textconv.c
+++ b/android/client/textconv.c
@@ -237,7 +237,7 @@ char *bdaddr2str(const bt_bdaddr_t *bd_addr)
 	return bt_bdaddr_t2str(bd_addr, bdaddr_tls_buffer);
 }
 
-static char *btuuid2str(const bt_uuid_t *uuid)
+char *btuuid2str(const bt_uuid_t *uuid)
 {
 	static char buf[MAX_UUID_STR_LEN];
 
diff --git a/android/client/textconv.h b/android/client/textconv.h
index 1c848ef..7520b04 100644
--- a/android/client/textconv.h
+++ b/android/client/textconv.h
@@ -109,6 +109,7 @@ void str2bt_uuid_t(const char *str, bt_uuid_t *uuid);
 
 char *btproperty2str(const bt_property_t *property);
 char *bdaddr2str(const bt_bdaddr_t *bd_addr);
+char *btuuid2str(const bt_uuid_t *uuid);
 
 DECINTMAP(bt_status_t);
 DECINTMAP(bt_state_t);
-- 
1.7.10.4


^ permalink raw reply related

* [PATCH 2/2] android/hal: Add UUID debug print in socket HAL
From: Andrei Emeltchenko @ 2013-11-05 14:06 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1383660378-23198-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

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

---
 android/hal-sock.c |   18 +++++++++++-------
 1 file changed, 11 insertions(+), 7 deletions(-)

diff --git a/android/hal-sock.c b/android/hal-sock.c
index 131877a..5e64409 100644
--- a/android/hal-sock.c
+++ b/android/hal-sock.c
@@ -25,6 +25,8 @@
 #include "hal-msg.h"
 #include "hal.h"
 
+#include "client/textconv.h"
+
 static bt_status_t sock_listen_rfcomm(const char *service_name,
 					const uint8_t *uuid, int chan,
 					int *sock, int flags)
@@ -49,13 +51,14 @@ static bt_status_t sock_listen(btsock_type_t type, const char *service_name,
 					int *sock, int flags)
 {
 	if ((!uuid && chan <= 0) || !sock) {
-		error("%s: invalid params: uuid %p, chan %d, sock %p",
-						__func__, uuid, chan, sock);
+		error("Invalid params: uuid %s, chan %d, sock %p",
+				btuuid2str((bt_uuid_t *) uuid), chan, sock);
 		return BT_STATUS_PARM_INVALID;
 	}
 
-	DBG("uuid %p chan %d sock %p type %d service_name %s",
-					uuid, chan, sock, type, service_name);
+	DBG("uuid %s chan %d sock %p type %d service_name %s",
+				btuuid2str((bt_uuid_t *) uuid), chan,
+				sock, type, service_name);
 
 	switch (type) {
 	case BTSOCK_RFCOMM:
@@ -76,12 +79,13 @@ static bt_status_t sock_connect(const bt_bdaddr_t *bdaddr, btsock_type_t type,
 	struct hal_op_sock_connect cmd;
 
 	if ((!uuid && chan <= 0) || !bdaddr || !sock) {
-		error("invalid params: bd_addr %p, uuid %p, chan %d, sock %p",
-					bdaddr, uuid, chan, sock);
+		error("Invalid params: bd_addr %p, uuid %s, chan %d, sock %p",
+			bdaddr, btuuid2str((bt_uuid_t *) uuid), chan, sock);
 		return BT_STATUS_PARM_INVALID;
 	}
 
-	DBG("uuid %p chan %d sock %p type %d", uuid, chan, sock, type);
+	DBG("uuid %s chan %d sock %p type %d", btuuid2str((bt_uuid_t *) uuid),
+							chan, sock, type);
 
 	cmd.flags = flags;
 	cmd.type = type;
-- 
1.7.10.4


^ permalink raw reply related

* [PATCH 1/5] adapter: Move MGMT_VERSION macro to mgmt.h
From: Szymon Janc @ 2013-11-05 14:18 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

This will be also used in Android daemon.
---
 src/adapter.c     | 1 -
 src/shared/mgmt.h | 2 ++
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/adapter.c b/src/adapter.c
index 30bcc4d..d904a56 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -99,7 +99,6 @@ static GSList *adapters = NULL;
 
 static struct mgmt *mgmt_master = NULL;
 
-#define MGMT_VERSION(v, r) ((v << 16) + (r))
 static uint8_t mgmt_version = 0;
 static uint8_t mgmt_revision = 0;
 
diff --git a/src/shared/mgmt.h b/src/shared/mgmt.h
index 60a2128..99ea96f 100644
--- a/src/shared/mgmt.h
+++ b/src/shared/mgmt.h
@@ -24,6 +24,8 @@
 #include <stdbool.h>
 #include <stdint.h>
 
+#define MGMT_VERSION(v, r) ((v << 16) + (r))
+
 typedef void (*mgmt_destroy_func_t)(void *user_data);
 
 struct mgmt;
-- 
1.8.4.2


^ permalink raw reply related

* [PATCH 2/5] android: Require at least 1.3 version of mgmt interface
From: Szymon Janc @ 2013-11-05 14:18 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1383661128-25029-1-git-send-email-szymon.janc@tieto.com>

Android daemon is not providing old kernels compatibility features.
---
 android/main.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/android/main.c b/android/main.c
index 7d36976..7ee47fc 100644
--- a/android/main.c
+++ b/android/main.c
@@ -608,8 +608,8 @@ static void read_version_complete(uint8_t status, uint16_t length,
 	info("Bluetooth management interface %u.%u initialized",
 						mgmt_version, mgmt_revision);
 
-	if (mgmt_version < 1) {
-		error("Version 1.0 or later of management interface required");
+	if (MGMT_VERSION(mgmt_version, mgmt_revision) < MGMT_VERSION(1, 3)) {
+		error("Version 1.3 or later of management interface required");
 		return;
 	}
 
-- 
1.8.4.2


^ permalink raw reply related

* [PATCH 3/5] android: Remove mgmt_version and mgmt_revision static variables
From: Szymon Janc @ 2013-11-05 14:18 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1383661128-25029-1-git-send-email-szymon.janc@tieto.com>

There is no need to keep those as Android daemon is expecting new
enough kernel to operate.
---
 android/main.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/android/main.c b/android/main.c
index 7ee47fc..d68abe1 100644
--- a/android/main.c
+++ b/android/main.c
@@ -68,9 +68,6 @@
 static GMainLoop *event_loop;
 static struct mgmt *mgmt_if = NULL;
 
-static uint8_t mgmt_version = 0;
-static uint8_t mgmt_revision = 0;
-
 static uint16_t adapter_index = MGMT_INDEX_NONE;
 static guint adapter_timeout = 0;
 
@@ -588,6 +585,7 @@ static void read_version_complete(uint8_t status, uint16_t length,
 					const void *param, void *user_data)
 {
 	const struct mgmt_rp_read_version *rp = param;
+	uint8_t mgmt_version, mgmt_revision;
 
 	DBG("");
 
-- 
1.8.4.2


^ permalink raw reply related

* [PATCH 4/5] android: Stop mainloop if reading version failed
From: Szymon Janc @ 2013-11-05 14:18 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1383661128-25029-1-git-send-email-szymon.janc@tieto.com>

If reading mgmt version failed or kernel supported version is to old
mainloop should be stopped.
---
 android/main.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/android/main.c b/android/main.c
index d68abe1..4bb5101 100644
--- a/android/main.c
+++ b/android/main.c
@@ -592,12 +592,12 @@ static void read_version_complete(uint8_t status, uint16_t length,
 	if (status) {
 		error("Failed to read version information: %s (0x%02x)",
 						mgmt_errstr(status), status);
-		return;
+		goto error;
 	}
 
 	if (length < sizeof(*rp)) {
 		error("Wrong size response");
-		return;
+		goto error;
 	}
 
 	mgmt_version = rp->version;
@@ -608,7 +608,7 @@ static void read_version_complete(uint8_t status, uint16_t length,
 
 	if (MGMT_VERSION(mgmt_version, mgmt_revision) < MGMT_VERSION(1, 3)) {
 		error("Version 1.3 or later of management interface required");
-		return;
+		goto error;
 	}
 
 	mgmt_send(mgmt_if, MGMT_OP_READ_COMMANDS, MGMT_INDEX_NONE, 0, NULL,
@@ -624,6 +624,9 @@ static void read_version_complete(uint8_t status, uint16_t length,
 		return;
 
 	error("Failed to read controller index list");
+
+error:
+	g_main_loop_quit(event_loop);
 }
 
 static bool init_mgmt_interface(void)
-- 
1.8.4.2


^ 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