Linux bluetooth development
 help / color / mirror / Atom feed
* bluez-5.10/monitor/packet.c:4335: possible missing break ?
From: David Binderman @ 2013-11-05 15:02 UTC (permalink / raw)
  To: linux-bluetooth@vger.kernel.org

Hello there,

I just ran the static analysis checker "cppcheck" over the source code of bluez-5.10

It said

[monitor/packet.c:4335] -> [monitor/packet.c:4338]: (warning) Variable 'str' is reassigned a value
 before the old one has been used. 'break;' missing?

Source code is

    case 0x03:
        str = "Allow Scan Request from White List Only, "
            "Allow Connect Request from White List Only";
    default:
        str = "Reserved";
        break;

Suggest add a break statement to the 0x03 case.

Regards

David Binderman 		 	   		  

^ permalink raw reply

* [PATCH 5/5] android: Stop mainloop if reading index list 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 index list failed mainloop should be stopped since adapter
init guard timer is not yet running.
---
 android/main.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/android/main.c b/android/main.c
index 4bb5101..72e47f2 100644
--- a/android/main.c
+++ b/android/main.c
@@ -528,12 +528,12 @@ static void read_index_list_complete(uint8_t status, uint16_t length,
 	if (status) {
 		error("%s: Failed to read index list: %s (0x%02x)",
 					__func__, mgmt_errstr(status), status);
-		return;
+		goto error;
 	}
 
 	if (length < sizeof(*rp)) {
 		error("%s: Wrong size of read index list response", __func__);
-		return;
+		goto error;
 	}
 
 	num = btohs(rp->num_controllers);
@@ -542,7 +542,7 @@ static void read_index_list_complete(uint8_t status, uint16_t length,
 
 	if (num * sizeof(uint16_t) + sizeof(*rp) != length) {
 		error("%s: Incorrect pkt size for index list rsp", __func__);
-		return;
+		goto error;
 	}
 
 	if (adapter_index != MGMT_INDEX_NONE)
@@ -553,13 +553,17 @@ static void read_index_list_complete(uint8_t status, uint16_t length,
 						adapter_timeout_handler, NULL);
 		if (adapter_timeout == 0) {
 			error("%s: Failed init timeout", __func__);
-			g_main_loop_quit(event_loop);
+			goto error;
 		}
 		return;
 	}
 
 	adapter_index = btohs(rp->index[0]);
 	bt_adapter_init(adapter_index, mgmt_if, adapter_ready);
+	return;
+
+error:
+	g_main_loop_quit(event_loop);
 }
 
 static void read_commands_complete(uint8_t status, uint16_t length,
-- 
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

* [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 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 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/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/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

* 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

* 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 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

* [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 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

* [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

* [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 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 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 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 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 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

* 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

* 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

* [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 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

* 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


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