Linux bluetooth development
 help / color / mirror / Atom feed
* Re: [PATCH_v3 1/4] android/pan: Register Network Access Point
From: Szymon Janc @ 2014-01-08  9:18 UTC (permalink / raw)
  To: Ravi kumar Veeramally; +Cc: linux-bluetooth
In-Reply-To: <1389097880-14783-2-git-send-email-ravikumar.veeramally@linux.intel.com>

Hi Ravi,

> Register NAP server and adds bnep bridge. Removes bridge
> on destroy call. Bridge mechanism is needed when device acting
> as a server and listen for incoming connections.
> ---
>  android/pan.c | 112 +++++++++++++++++++++++++++++++++++++++++++++++++++++++---
>  1 file changed, 108 insertions(+), 4 deletions(-)
> 
> diff --git a/android/pan.c b/android/pan.c
> index 38e353d..93078ba 100644
> --- a/android/pan.c
> +++ b/android/pan.c
> @@ -28,6 +28,11 @@
>  #include <unistd.h>
>  #include <fcntl.h>
>  #include <glib.h>
> +#include <sys/ioctl.h>
> +#include <sys/socket.h>
> +#include <sys/wait.h>
> +#include <net/if.h>
> +#include <linux/sockios.h>
>  
>  #include "btio/btio.h"
>  #include "lib/bluetooth.h"
> @@ -45,11 +50,11 @@
>  #include "bluetooth.h"
>  
>  #define SVC_HINT_NETWORKING 0x02
> +#define BNEP_BRIDGE	"bnep"
>  
>  static bdaddr_t adapter_addr;
>  GSList *devices = NULL;
>  uint8_t local_role = HAL_PAN_ROLE_NONE;
> -static uint32_t record_id = 0;
>  
>  struct pan_device {
>  	char		iface[16];
> @@ -60,6 +65,12 @@ struct pan_device {
>  	struct bnep	*session;
>  };
>  
> +static struct {
> +	uint32_t	record_id;
> +} nap_dev = {
> +	.record_id = 0,
> +};
> +
>  static int device_cmp(gconstpointer s, gconstpointer user_data)
>  {
>  	const struct pan_device *dev = s;
> @@ -297,6 +308,91 @@ failed:
>  	ipc_send_rsp(HAL_SERVICE_ID_PAN, HAL_OP_PAN_DISCONNECT, status);
>  }
>  
> +static int set_forward_delay(void)
> +{
> +	int fd, ret;
> +	char path[41];
> +
> +	sprintf(path, "/sys/class/net/%s/bridge/forward_delay", BNEP_BRIDGE);
> +
> +	fd = open(path, O_RDWR);
> +	if (fd < 0)
> +		return -errno;
> +
> +	ret = write(fd, "0", sizeof("0"));
> +	close(fd);
> +
> +	return ret;
> +}
> +
> +static int nap_create_bridge(void)
> +{
> +	int sk, err;
> +
> +	DBG("%s", BNEP_BRIDGE);
> +
> +	sk = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
> +	if (sk < 0)
> +		return -EOPNOTSUPP;
> +
> +	if (ioctl(sk, SIOCBRADDBR, BNEP_BRIDGE) < 0) {
> +		err = -errno;
> +		if (err != -EEXIST) {
> +			close(sk);
> +			return -EOPNOTSUPP;
> +		}
> +	}
> +
> +	err = set_forward_delay();
> +	if (err < 0)
> +		ioctl(sk, SIOCBRDELBR, BNEP_BRIDGE);
> +
> +	close(sk);
> +
> +	return err;
> +}
> +
> +static int nap_remove_bridge(void)
> +{
> +	int sk, err;
> +
> +	DBG("%s", BNEP_BRIDGE);
> +
> +	sk = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
> +	if (sk < 0)
> +		return -EOPNOTSUPP;
> +
> +	err = ioctl(sk, SIOCBRDELBR, BNEP_BRIDGE);
> +	close(sk);
> +
> +	if (err < 0)
> +		return -EOPNOTSUPP;
> +
> +	return 0;
> +}
> +
> +static void destroy_nap_device(void)
> +{
> +	DBG("");
> +
> +	nap_remove_bridge();
> +
> +	nap_dev.record_id = 0;
> +}
> +
> +static int register_nap_server(void)
> +{
> +	int err;
> +
> +	DBG("");
> +
> +	err = nap_create_bridge();
> +	if (err < 0)
> +		return err;
> +
> +	return 0;
> +}
> +
>  static void bt_pan_enable(const void *buf, uint16_t len)
>  {
>  	const struct hal_cmd_pan_enable *cmd = buf;
> @@ -441,7 +537,15 @@ bool bt_pan_register(const bdaddr_t *addr)
>  		return false;
>  	}
>  
> -	record_id = rec->handle;
> +	err = register_nap_server();
> +	if (err < 0) {
> +		bt_adapter_remove_record(rec->handle);
> +		sdp_record_free(rec);
> +		bnep_cleanup();
> +		return false;
> +	}
> +
> +	nap_dev.record_id = rec->handle;
>  	ipc_register(HAL_SERVICE_ID_PAN, cmd_handlers,
>  						G_N_ELEMENTS(cmd_handlers));
>  
> @@ -455,6 +559,6 @@ void bt_pan_unregister(void)
>  	bnep_cleanup();
>  
>  	ipc_unregister(HAL_SERVICE_ID_PAN);
> -	bt_adapter_remove_record(record_id);
> -	record_id = 0;
> +	bt_adapter_remove_record(nap_dev.record_id);
> +	destroy_nap_device();

I would either zero nap_dev.record_id right after removing record or move
removing record to destroy_nap_device().

-- 
BR
Szymon Janc


^ permalink raw reply

* [PATCHv3 1/5] tools/rfcomm-tester: Initial version of rfcomm-tester
From: Marcin Kraglak @ 2014-01-08  9:23 UTC (permalink / raw)
  To: linux-bluetooth

Add rfcomm-tester to tree.
---
 .gitignore            |  1 +
 Makefile.tools        |  6 +++++-
 tools/rfcomm-tester.c | 36 ++++++++++++++++++++++++++++++++++++
 3 files changed, 42 insertions(+), 1 deletion(-)
 create mode 100644 tools/rfcomm-tester.c

diff --git a/.gitignore b/.gitignore
index 3e0641d..4ac216d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -81,6 +81,7 @@ unit/test-mgmt
 tools/mgmt-tester
 tools/smp-tester
 tools/gap-tester
+tools/rfcomm-tester
 tools/btattach
 tools/btmgmt
 tools/btsnoop
diff --git a/Makefile.tools b/Makefile.tools
index c78cc50..ef17305 100644
--- a/Makefile.tools
+++ b/Makefile.tools
@@ -39,7 +39,7 @@ if EXPERIMENTAL
 noinst_PROGRAMS += emulator/btvirt emulator/b1ee tools/3dsp \
 					tools/mgmt-tester tools/gap-tester \
 					tools/l2cap-tester tools/sco-tester \
-					tools/smp-tester
+					tools/smp-tester tools/rfcomm-tester
 
 emulator_btvirt_SOURCES = emulator/main.c monitor/bt.h \
 					monitor/mainloop.h monitor/mainloop.c \
@@ -76,6 +76,10 @@ tools_l2cap_tester_SOURCES = tools/l2cap-tester.c monitor/bt.h \
 				src/shared/tester.h src/shared/tester.c
 tools_l2cap_tester_LDADD = lib/libbluetooth-internal.la @GLIB_LIBS@
 
+tools_rfcomm_tester_SOURCES = tools/rfcomm-tester.c src/shared/tester.h \
+				src/shared/tester.c
+tools_rfcomm_tester_LDADD = lib/libbluetooth-internal.la @GLIB_LIBS@
+
 tools_smp_tester_SOURCES = tools/smp-tester.c monitor/bt.h \
 				emulator/btdev.h emulator/btdev.c \
 				emulator/bthost.h emulator/bthost.c \
diff --git a/tools/rfcomm-tester.c b/tools/rfcomm-tester.c
new file mode 100644
index 0000000..200d953
--- /dev/null
+++ b/tools/rfcomm-tester.c
@@ -0,0 +1,36 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2014  Intel Corporation. All rights reserved.
+ *
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib.h>
+#include "src/shared/tester.h"
+
+int main(int argc, char *argv[])
+{
+	tester_init(&argc, &argv);
+
+	return tester_run();
+}
-- 
1.8.3.1


^ permalink raw reply related

* [PATCHv3 2/5] tools/rfcomm-tester: Add basic rfcomm test case
From: Marcin Kraglak @ 2014-01-08  9:23 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1389173030-27970-1-git-send-email-marcin.kraglak@tieto.com>

This test case verifies creating rfcomm socket.
---
 Makefile.tools        |   9 +-
 tools/rfcomm-tester.c | 249 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 256 insertions(+), 2 deletions(-)

diff --git a/Makefile.tools b/Makefile.tools
index ef17305..6f716fd 100644
--- a/Makefile.tools
+++ b/Makefile.tools
@@ -76,8 +76,13 @@ tools_l2cap_tester_SOURCES = tools/l2cap-tester.c monitor/bt.h \
 				src/shared/tester.h src/shared/tester.c
 tools_l2cap_tester_LDADD = lib/libbluetooth-internal.la @GLIB_LIBS@
 
-tools_rfcomm_tester_SOURCES = tools/rfcomm-tester.c src/shared/tester.h \
-				src/shared/tester.c
+tools_rfcomm_tester_SOURCES = tools/rfcomm-tester.c monitor/bt.h \
+				emulator/btdev.h emulator/btdev.c \
+				emulator/bthost.h emulator/bthost.c \
+				src/shared/util.h src/shared/util.c \
+				src/shared/mgmt.h src/shared/mgmt.c \
+				src/shared/hciemu.h src/shared/hciemu.c \
+				src/shared/tester.h src/shared/tester.c
 tools_rfcomm_tester_LDADD = lib/libbluetooth-internal.la @GLIB_LIBS@
 
 tools_smp_tester_SOURCES = tools/smp-tester.c monitor/bt.h \
diff --git a/tools/rfcomm-tester.c b/tools/rfcomm-tester.c
index 200d953..a4f1c8e 100644
--- a/tools/rfcomm-tester.c
+++ b/tools/rfcomm-tester.c
@@ -25,12 +25,261 @@
 #include <config.h>
 #endif
 
+#include <stdlib.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdbool.h>
+
 #include <glib.h>
+
+#include "lib/bluetooth.h"
+#include "lib/mgmt.h"
+
+#include "monitor/bt.h"
+#include "emulator/bthost.h"
+
 #include "src/shared/tester.h"
+#include "src/shared/mgmt.h"
+#include "src/shared/hciemu.h"
+
+struct test_data {
+	struct mgmt *mgmt;
+	uint16_t mgmt_index;
+	struct hciemu *hciemu;
+	enum hciemu_type hciemu_type;
+	const void *test_data;
+};
+
+static void mgmt_debug(const char *str, void *user_data)
+{
+	const char *prefix = user_data;
+
+	tester_print("%s%s", prefix, str);
+}
+
+static void read_info_callback(uint8_t status, uint16_t length,
+					const void *param, void *user_data)
+{
+	struct test_data *data = tester_get_data();
+	const struct mgmt_rp_read_info *rp = param;
+	char addr[18];
+	uint16_t manufacturer;
+	uint32_t supported_settings, current_settings;
+
+	tester_print("Read Info callback");
+	tester_print("  Status: 0x%02x", status);
+
+	if (status || !param) {
+		tester_pre_setup_failed();
+		return;
+	}
+
+	ba2str(&rp->bdaddr, addr);
+	manufacturer = btohs(rp->manufacturer);
+	supported_settings = btohl(rp->supported_settings);
+	current_settings = btohl(rp->current_settings);
+
+	tester_print("  Address: %s", addr);
+	tester_print("  Version: 0x%02x", rp->version);
+	tester_print("  Manufacturer: 0x%04x", manufacturer);
+	tester_print("  Supported settings: 0x%08x", supported_settings);
+	tester_print("  Current settings: 0x%08x", current_settings);
+	tester_print("  Class: 0x%02x%02x%02x",
+			rp->dev_class[2], rp->dev_class[1], rp->dev_class[0]);
+	tester_print("  Name: %s", rp->name);
+	tester_print("  Short name: %s", rp->short_name);
+
+	if (strcmp(hciemu_get_address(data->hciemu), addr)) {
+		tester_pre_setup_failed();
+		return;
+	}
+
+	tester_pre_setup_complete();
+}
+
+static void index_added_callback(uint16_t index, uint16_t length,
+					const void *param, void *user_data)
+{
+	struct test_data *data = tester_get_data();
+
+	tester_print("Index Added callback");
+	tester_print("  Index: 0x%04x", index);
+
+	data->mgmt_index = index;
+
+	mgmt_send(data->mgmt, MGMT_OP_READ_INFO, data->mgmt_index, 0, NULL,
+					read_info_callback, NULL, NULL);
+}
+
+static void index_removed_callback(uint16_t index, uint16_t length,
+					const void *param, void *user_data)
+{
+	struct test_data *data = tester_get_data();
+
+	tester_print("Index Removed callback");
+	tester_print("  Index: 0x%04x", index);
+
+	if (index != data->mgmt_index)
+		return;
+
+	mgmt_unregister_index(data->mgmt, data->mgmt_index);
+
+	mgmt_unref(data->mgmt);
+	data->mgmt = NULL;
+
+	tester_post_teardown_complete();
+}
+
+static void read_index_list_callback(uint8_t status, uint16_t length,
+					const void *param, void *user_data)
+{
+	struct test_data *data = tester_get_data();
+
+	tester_print("Read Index List callback");
+	tester_print("  Status: 0x%02x", status);
+
+	if (status || !param) {
+		tester_pre_setup_failed();
+		return;
+	}
+
+	mgmt_register(data->mgmt, MGMT_EV_INDEX_ADDED, MGMT_INDEX_NONE,
+					index_added_callback, NULL, NULL);
+
+	mgmt_register(data->mgmt, MGMT_EV_INDEX_REMOVED, MGMT_INDEX_NONE,
+					index_removed_callback, NULL, NULL);
+
+	data->hciemu = hciemu_new(data->hciemu_type);
+	if (!data->hciemu) {
+		tester_warn("Failed to setup HCI emulation");
+		tester_pre_setup_failed();
+	}
+
+	tester_print("New hciemu instance created");
+}
+
+static void test_pre_setup(const void *test_data)
+{
+	struct test_data *data = tester_get_data();
+
+	data->mgmt = mgmt_new_default();
+	if (!data->mgmt) {
+		tester_warn("Failed to setup management interface");
+		tester_pre_setup_failed();
+		return;
+	}
+
+	if (tester_use_debug())
+		mgmt_set_debug(data->mgmt, mgmt_debug, "mgmt: ", NULL);
+
+	mgmt_send(data->mgmt, MGMT_OP_READ_INDEX_LIST, MGMT_INDEX_NONE, 0, NULL,
+					read_index_list_callback, NULL, NULL);
+}
+
+static void test_post_teardown(const void *test_data)
+{
+	struct test_data *data = tester_get_data();
+
+	hciemu_unref(data->hciemu);
+	data->hciemu = NULL;
+}
+
+static void test_data_free(void *test_data)
+{
+	struct test_data *data = test_data;
+
+	free(data);
+}
+
+static void client_connectable_complete(uint16_t opcode, uint8_t status,
+					const void *param, uint8_t len,
+					void *user_data)
+{
+	switch (opcode) {
+	case BT_HCI_CMD_WRITE_SCAN_ENABLE:
+		break;
+	default:
+		return;
+	}
+
+	tester_print("Client set connectable status 0x%02x", status);
+
+	if (status)
+		tester_setup_failed();
+	else
+		tester_setup_complete();
+}
+
+static void setup_powered_client_callback(uint8_t status, uint16_t length,
+					const void *param, void *user_data)
+{
+	struct test_data *data = tester_get_data();
+	struct bthost *bthost;
+
+	if (status != MGMT_STATUS_SUCCESS) {
+		tester_setup_failed();
+		return;
+	}
+
+	tester_print("Controller powered on");
+
+	bthost = hciemu_client_get_host(data->hciemu);
+	bthost_set_cmd_complete_cb(bthost, client_connectable_complete, data);
+	bthost_write_scan_enable(bthost, 0x03);
+}
+
+static void setup_powered_client(const void *test_data)
+{
+	struct test_data *data = tester_get_data();
+	unsigned char param[] = { 0x01 };
+
+	tester_print("Powering on controller");
+
+	mgmt_send(data->mgmt, MGMT_OP_SET_SSP, data->mgmt_index,
+				sizeof(param), param, NULL, NULL, NULL);
+
+	mgmt_send(data->mgmt, MGMT_OP_SET_POWERED, data->mgmt_index,
+			sizeof(param), param, setup_powered_client_callback,
+			NULL, NULL);
+}
+
+static void test_basic(const void *test_data)
+{
+	int sk;
+
+	sk = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
+	if (sk < 0) {
+		tester_warn("Can't create socket: %s (%d)", strerror(errno),
+									errno);
+		tester_test_failed();
+		return;
+	}
+
+	close(sk);
+
+	tester_test_passed();
+}
+
+#define test_rfcomm(name, data, setup, func) \
+	do { \
+		struct test_data *user; \
+		user = malloc(sizeof(struct test_data)); \
+		if (!user) \
+			break; \
+		user->hciemu_type = HCIEMU_TYPE_BREDR; \
+		user->test_data = data; \
+		tester_add_full(name, data, \
+				test_pre_setup, setup, func, NULL, \
+				test_post_teardown, 2, user, test_data_free); \
+	} while (0)
 
 int main(int argc, char *argv[])
 {
 	tester_init(&argc, &argv);
 
+	test_rfcomm("Basic RFCOMM Socket - Success", NULL,
+					setup_powered_client, test_basic);
+
 	return tester_run();
 }
-- 
1.8.3.1


^ permalink raw reply related

* [PATCHv3 3/5] monitor: Add rfcomm.h to tree
From: Marcin Kraglak @ 2014-01-08  9:23 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1389173030-27970-1-git-send-email-marcin.kraglak@tieto.com>

Add initial rfcomm structs and defines to rfcomm.h.
---
 monitor/rfcomm.h | 47 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 47 insertions(+)
 create mode 100644 monitor/rfcomm.h

diff --git a/monitor/rfcomm.h b/monitor/rfcomm.h
new file mode 100644
index 0000000..8dcb9c1
--- /dev/null
+++ b/monitor/rfcomm.h
@@ -0,0 +1,47 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2014 Intel Corporation
+ *
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#define RFCOMM_SABM	0x2f
+#define RFCOMM_DISC	0x43
+#define RFCOMM_UA	0x63
+#define RFCOMM_DM	0x0f
+#define RFCOMM_UIH	0xef
+
+#define RFCOMM_GET_TYPE(control)	((control) & 0xef)
+#define RFCOMM_GET_DLCI(address)	((address & 0xfc) >> 2)
+#define RFCOMM_GET_CHANNEL(address)	((address & 0xf8) >> 3)
+#define RFCOMM_GET_DIR(address)	((address & 0x04) >> 2)
+#define RFCOMM_TEST_EA(length)	((length & 0x01))
+
+struct rfcomm_hdr {
+	uint8_t address;
+	uint8_t control;
+	uint8_t length;
+} __attribute__((packed));
+
+struct rfcomm_cmd {
+	uint8_t address;
+	uint8_t control;
+	uint8_t length;
+	uint8_t fcs;
+} __attribute__((packed));
-- 
1.8.3.1


^ permalink raw reply related

* [PATCHv3 4/5] emulator/bthost: Add initial rfcomm handling
From: Marcin Kraglak @ 2014-01-08  9:23 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1389173030-27970-1-git-send-email-marcin.kraglak@tieto.com>

This is initial rfcomm handling in bthost.
---
 emulator/bthost.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 66 insertions(+), 1 deletion(-)

diff --git a/emulator/bthost.c b/emulator/bthost.c
index 83bfdee..5e13745 100644
--- a/emulator/bthost.c
+++ b/emulator/bthost.c
@@ -36,6 +36,7 @@
 #include "bluetooth/bluetooth.h"
 
 #include "monitor/bt.h"
+#include "monitor/rfcomm.h"
 #include "bthost.h"
 
 /* ACL handle and flags pack/unpack */
@@ -1173,6 +1174,64 @@ static struct cid_hook *find_cid_hook(struct btconn *conn, uint16_t cid)
 	return NULL;
 }
 
+static void rfcomm_sabm_recv(struct bthost *bthost, struct btconn *conn,
+				struct l2conn *l2conn, const void *data,
+				uint16_t len)
+{
+}
+
+static void rfcomm_disc_recv(struct bthost *bthost, struct btconn *conn,
+				struct l2conn *l2conn, const void *data,
+				uint16_t len)
+{
+}
+
+static void rfcomm_ua_recv(struct bthost *bthost, struct btconn *conn,
+				struct l2conn *l2conn, const void *data,
+				uint16_t len)
+{
+}
+
+static void rfcomm_dm_recv(struct bthost *bthost, struct btconn *conn,
+				struct l2conn *l2conn, const void *data,
+				uint16_t len)
+{
+}
+
+static void rfcomm_uih_recv(struct bthost *bthost, struct btconn *conn,
+				struct l2conn *l2conn, const void *data,
+				uint16_t len)
+{
+}
+
+static void process_rfcomm(struct bthost *bthost, struct btconn *conn,
+				struct l2conn *l2conn, const void *data,
+				uint16_t len)
+{
+	const struct rfcomm_hdr *hdr = data;
+
+	switch (RFCOMM_GET_TYPE(hdr->control)) {
+	case RFCOMM_SABM:
+		rfcomm_sabm_recv(bthost, conn, l2conn, data, len);
+		break;
+	case RFCOMM_DISC:
+		rfcomm_disc_recv(bthost, conn, l2conn, data, len);
+		break;
+	case RFCOMM_UA:
+		rfcomm_ua_recv(bthost, conn, l2conn, data, len);
+		break;
+	case RFCOMM_DM:
+		rfcomm_dm_recv(bthost, conn, l2conn, data, len);
+		break;
+	case RFCOMM_UIH:
+		rfcomm_uih_recv(bthost, conn, l2conn, data, len);
+		break;
+	default:
+		printf("Unknown frame type\n");
+		break;
+	}
+}
+
 static void process_acl(struct bthost *bthost, const void *data, uint16_t len)
 {
 	const struct bt_hci_acl_hdr *acl_hdr = data;
@@ -1180,6 +1239,7 @@ static void process_acl(struct bthost *bthost, const void *data, uint16_t len)
 	uint16_t handle, cid, acl_len, l2_len;
 	struct cid_hook *hook;
 	struct btconn *conn;
+	struct l2conn *l2conn;
 	const void *l2_data;
 
 	if (len < sizeof(*acl_hdr) + sizeof(*l2_hdr))
@@ -1218,7 +1278,12 @@ static void process_acl(struct bthost *bthost, const void *data, uint16_t len)
 		l2cap_le_sig(bthost, conn, l2_data, l2_len);
 		break;
 	default:
-		printf("Packet for unknown CID 0x%04x (%u)\n", cid, cid);
+		l2conn = btconn_find_l2cap_conn_by_scid(conn, cid);
+		if (l2conn && l2conn->psm == 0x0003)
+			process_rfcomm(bthost, conn, l2conn, l2_data, l2_len);
+		else
+			printf("Packet for unknown CID 0x%04x (%u)\n", cid,
+									cid);
 		break;
 	}
 }
-- 
1.8.3.1


^ permalink raw reply related

* [PATCHv3 5/5] emulator/bthost: Add method to create rfcomm server
From: Marcin Kraglak @ 2014-01-08  9:23 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1389173030-27970-1-git-send-email-marcin.kraglak@tieto.com>

It allows user to create rfcomm server on bthost.
---
 emulator/bthost.c | 32 ++++++++++++++++++++++++++++++++
 emulator/bthost.h |  6 ++++++
 2 files changed, 38 insertions(+)

diff --git a/emulator/bthost.c b/emulator/bthost.c
index 5e13745..8d53923 100644
--- a/emulator/bthost.c
+++ b/emulator/bthost.c
@@ -99,6 +99,13 @@ struct l2cap_conn_cb_data {
 	struct l2cap_conn_cb_data *next;
 };
 
+struct rfcomm_conn_cb_data {
+	uint8_t channel;
+	bthost_rfcomm_connect_cb func;
+	void *user_data;
+	struct rfcomm_conn_cb_data *next;
+};
+
 struct bthost {
 	uint8_t bdaddr[6];
 	bthost_send_func send_handler;
@@ -111,6 +118,7 @@ struct bthost {
 	bthost_new_conn_cb new_conn_cb;
 	void *new_conn_data;
 	struct l2cap_conn_cb_data *new_l2cap_conn_data;
+	struct rfcomm_conn_cb_data *new_rfcomm_conn_data;
 	struct l2cap_pending_req *l2reqs;
 };
 
@@ -246,6 +254,13 @@ void bthost_destroy(struct bthost *bthost)
 		free(cb);
 	}
 
+	while (bthost->new_rfcomm_conn_data) {
+		struct rfcomm_conn_cb_data *cb = bthost->new_rfcomm_conn_data;
+
+		bthost->new_rfcomm_conn_data = cb->next;
+		free(cb);
+	}
+
 	free(bthost);
 }
 
@@ -1392,6 +1407,23 @@ void bthost_add_l2cap_server(struct bthost *bthost, uint16_t psm,
 	bthost->new_l2cap_conn_data = data;
 }
 
+void bthost_add_rfcomm_server(struct bthost *bthost, uint8_t channel,
+				bthost_rfcomm_connect_cb func, void *user_data)
+{
+	struct rfcomm_conn_cb_data *data;
+
+	data = malloc(sizeof(struct rfcomm_conn_cb_data));
+	if (!data)
+		return;
+
+	data->channel = channel;
+	data->user_data = user_data;
+	data->func = func;
+	data->next = bthost->new_rfcomm_conn_data;
+
+	bthost->new_rfcomm_conn_data = data;
+}
+
 void bthost_start(struct bthost *bthost)
 {
 	if (!bthost)
diff --git a/emulator/bthost.h b/emulator/bthost.h
index 97f011b..7186aa0 100644
--- a/emulator/bthost.h
+++ b/emulator/bthost.h
@@ -80,5 +80,11 @@ typedef void (*bthost_l2cap_connect_cb) (uint16_t handle, uint16_t cid,
 void bthost_add_l2cap_server(struct bthost *bthost, uint16_t psm,
 				bthost_l2cap_connect_cb func, void *user_data);
 
+typedef void (*bthost_rfcomm_connect_cb) (uint16_t handle, uint16_t cid,
+					uint8_t channel, void *user_data);
+
+void bthost_add_rfcomm_server(struct bthost *bthost, uint8_t channel,
+			bthost_rfcomm_connect_cb func, void *user_data);
+
 void bthost_start(struct bthost *bthost);
 void bthost_stop(struct bthost *bthost);
-- 
1.8.3.1


^ permalink raw reply related

* Re: [PATCH_v3 3/4] android/pan: Implement PAN enable HAL api at daemon side
From: Szymon Janc @ 2014-01-08  9:24 UTC (permalink / raw)
  To: Ravi kumar Veeramally; +Cc: linux-bluetooth
In-Reply-To: <1389097880-14783-4-git-send-email-ravikumar.veeramally@linux.intel.com>

Hi Ravi,

> ---
>  android/pan.c | 32 ++++++++++++++++++++++++++------
>  1 file changed, 26 insertions(+), 6 deletions(-)
> 
> diff --git a/android/pan.c b/android/pan.c
> index 0eef284..0e12245 100644
> --- a/android/pan.c
> +++ b/android/pan.c
> @@ -585,18 +585,38 @@ static void bt_pan_enable(const void *buf, uint16_t len)
>  {
>  	const struct hal_cmd_pan_enable *cmd = buf;
>  	uint8_t status;
> +	int err;
> +
> +	DBG("");
> +
> +	if (local_role == cmd->local_role) {
> +		status = HAL_STATUS_SUCCESS;
> +		goto reply;
> +	}
> +
> +	/* destroy existing server */
> +	destroy_nap_device();
>  
>  	switch (cmd->local_role) {
>  	case HAL_PAN_ROLE_PANU:
> -	case HAL_PAN_ROLE_NAP:
> -		DBG("Not Implemented");
> -		status  = HAL_STATUS_FAILED;
> -		break;
> -	default:
>  		status = HAL_STATUS_UNSUPPORTED;
> -		break;
> +		goto reply;
> +	case HAL_PAN_ROLE_NONE:
> +		status = HAL_STATUS_SUCCESS;
> +		goto reply;
> +	}

Why do you remove default here? Daemon should verify parameter correctness.

> +
> +	local_role = cmd->local_role;
> +	err = register_nap_server();
> +	if (err < 0) {
> +		status = HAL_STATUS_FAILED;
> +		destroy_nap_device();
> +		goto reply;
>  	}
>  
> +	status = HAL_STATUS_SUCCESS;
> +
> +reply:
>  	ipc_send_rsp(HAL_SERVICE_ID_PAN, HAL_OP_PAN_ENABLE, status);
>  }
>  
> 

-- 
BR
Szymon Janc



^ permalink raw reply

* Re: [PATCH_v3 1/4] android/pan: Register Network Access Point
From: Ravi kumar Veeramally @ 2014-01-08  9:27 UTC (permalink / raw)
  To: Szymon Janc; +Cc: linux-bluetooth
In-Reply-To: <1697122.rgbbQeg154@uw000953>

Hi Szymon,

On 01/08/2014 11:18 AM, Szymon Janc wrote:
> Hi Ravi,
>
>> +
>> +	nap_dev.record_id = rec->handle;
>>   	ipc_register(HAL_SERVICE_ID_PAN, cmd_handlers,
>>   						G_N_ELEMENTS(cmd_handlers));
>>   
>> @@ -455,6 +559,6 @@ void bt_pan_unregister(void)
>>   	bnep_cleanup();
>>   
>>   	ipc_unregister(HAL_SERVICE_ID_PAN);
>> -	bt_adapter_remove_record(record_id);
>> -	record_id = 0;
>> +	bt_adapter_remove_record(nap_dev.record_id);
>> +	destroy_nap_device();
> I would either zero nap_dev.record_id right after removing record or move
> removing record to destroy_nap_device().

  OK, I will zero it right after removing record.

  Thanks,
  Ravi.

^ permalink raw reply

* Re: [PATCH_v3 3/4] android/pan: Implement PAN enable HAL api at daemon side
From: Ravi kumar Veeramally @ 2014-01-08  9:29 UTC (permalink / raw)
  To: Szymon Janc; +Cc: linux-bluetooth
In-Reply-To: <7986762.b1HJLuCvE7@uw000953>

Hi Szymon,

On 01/08/2014 11:24 AM, Szymon Janc wrote:
> Hi Ravi,
>
>> ---
>>   android/pan.c | 32 ++++++++++++++++++++++++++------
>>   1 file changed, 26 insertions(+), 6 deletions(-)
>>
>> diff --git a/android/pan.c b/android/pan.c
>> index 0eef284..0e12245 100644
>> --- a/android/pan.c
>> +++ b/android/pan.c
>> @@ -585,18 +585,38 @@ static void bt_pan_enable(const void *buf, uint16_t len)
>>   {
>>   	const struct hal_cmd_pan_enable *cmd = buf;
>>   	uint8_t status;
>> +	int err;
>> +
>> +	DBG("");
>> +
>> +	if (local_role == cmd->local_role) {
>> +		status = HAL_STATUS_SUCCESS;
>> +		goto reply;
>> +	}
>> +
>> +	/* destroy existing server */
>> +	destroy_nap_device();
>>   
>>   	switch (cmd->local_role) {
>>   	case HAL_PAN_ROLE_PANU:
>> -	case HAL_PAN_ROLE_NAP:
>> -		DBG("Not Implemented");
>> -		status  = HAL_STATUS_FAILED;
>> -		break;
>> -	default:
>>   		status = HAL_STATUS_UNSUPPORTED;
>> -		break;
>> +		goto reply;
>> +	case HAL_PAN_ROLE_NONE:
>> +		status = HAL_STATUS_SUCCESS;
>> +		goto reply;
>> +	}
> Why do you remove default here? Daemon should verify parameter correctness.

   Yes, default should be there, I think I was still in the impression of
  HAL side parameter validation. I will correct it in next version.

  Thanks,
  Ravi.
>
>> +
>> +	local_role = cmd->local_role;
>> +	err = register_nap_server();
>> +	if (err < 0) {
>> +		status = HAL_STATUS_FAILED;
>> +		destroy_nap_device();
>> +		goto reply;
>>   	}
>>   
>> +	status = HAL_STATUS_SUCCESS;
>> +
>> +reply:
>>   	ipc_send_rsp(HAL_SERVICE_ID_PAN, HAL_OP_PAN_ENABLE, status);
>>   }
>>   
>>


^ permalink raw reply

* Re: [PATCH_v3 2/4] android/pan: Listen for incoming connections and accept in NAP role
From: Ravi kumar Veeramally @ 2014-01-08  9:34 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <CABBYNZJHnUd9z6SRt84=OCXueBru9f5ae_m2SR06ujJzjQidBQ@mail.gmail.com>

Hi Luiz,

On 01/08/2014 11:07 AM, Luiz Augusto von Dentz wrote:
> Hi Ravi,
>
> On Tue, Jan 7, 2014 at 2:31 PM, Ravi kumar Veeramally
> <ravikumar.veeramally@linux.intel.com> wrote:
>> Listen for incoming connections and accept it. Create bnep interface
>> add it to bridge and notify control and connection state information
>> through HAL. Remove the device on disconnect request. If android
>> settings UI does not have bluetooth tethering enabled it immediately
>> sends disconnect signal.
>> ---
>>   android/pan.c | 192 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
>>   1 file changed, 190 insertions(+), 2 deletions(-)
>>
>> diff --git a/android/pan.c b/android/pan.c
>> index 93078ba..0eef284 100644
>> --- a/android/pan.c
>> +++ b/android/pan.c
>> @@ -63,12 +63,17 @@ struct pan_device {
>>          uint8_t         role;
>>          GIOChannel      *io;
>>          struct bnep     *session;
>> +       guint           watch;
>>   };
>>
>>   static struct {
>>          uint32_t        record_id;
>> +       guint           watch;
>> +       GIOChannel      *io;
>>   } nap_dev = {
>>          .record_id = 0,
>> +       .watch = 0,
>> +       .io = NULL,
>>   };
>>
>>   static int device_cmp(gconstpointer s, gconstpointer user_data)
>> @@ -81,13 +86,21 @@ static int device_cmp(gconstpointer s, gconstpointer user_data)
>>
>>   static void pan_device_free(struct pan_device *dev)
>>   {
>> +       if (dev->watch > 0) {
>> +               bnep_server_delete(BNEP_BRIDGE, dev->iface, &dev->dst);
>> +               g_source_remove(dev->watch);
>> +               dev->watch = 0;
> Usually it is not necessary to assign anything to struct members when
> you are freeing the whole struct since its memory gonna be freed
> anyway.

   Yes you are right. Profiles/network/connection.c keeps device data 
after disconnecting,
   it will remove only on device remove call. Assigning zero or NULL 
make sense there.
   But in bluez-android device struct t is removed from list on 
disconnected state.
   Here it won't make much sense. I will remove it in my next version.

  Thanks,
  Ravi.

^ permalink raw reply

* [PATCH] android/pics: Update PICS to PTS 5.0 for GAP
From: Sebastian Chlad @ 2014-01-08  9:46 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Sebastian Chlad

Add new PICS settings for the GAP profile in accordance with PTS 5.0
---
 android/pics-gap.txt | 44 +++++++++++++++++++++++++++++++++++++-------
 1 file changed, 37 insertions(+), 7 deletions(-)

diff --git a/android/pics-gap.txt b/android/pics-gap.txt
index e8ab2ab..56a33d5 100644
--- a/android/pics-gap.txt
+++ b/android/pics-gap.txt
@@ -1,5 +1,7 @@
 GAP PICS for the PTS tool.
 
+PTS version: 5.0
+
 * - different than PTS defaults
 # - not yet implemented/supported
 
@@ -668,19 +670,33 @@ TSPC_GAP_41_1	True (#)	Central BR/EDR/LE: Security Aspects (M)
 -------------------------------------------------------------------------------
 
 
+		Central Simultaneous BR/EDR and LE Transports
+-------------------------------------------------------------------------------
+Parameter Name	Selected	Description
+-------------------------------------------------------------------------------
+TSPC_GAP_42_1	False		Simultaneous BR/EDR and LE Transports –	BR/EDR
+					Slave to the same device (C.1)
+TSPC_GAP_42_2	False		Simultaneous BR/EDR and LE Transports – BR/EDR
+					Master to the same device (C.1)
+-------------------------------------------------------------------------------
+C.1: Optional if ((SUM ICS 31/14 (Core Spec Version 4.1) or SUM ICS 31/15
+	(Core Spec Version 4.1+HS)) is supported, otherwise Excluded.
+-------------------------------------------------------------------------------
+
+
 		Peripheral BR/EDR/LE Modes
 -------------------------------------------------------------------------------
 Parameter Name	Selected	Description
 -------------------------------------------------------------------------------
-TSPC_GAP_42_1	False		Peripheral BR/EDR/LE: Non-Discoverable Mode
+TSPC_GAP_43_1	False		Peripheral BR/EDR/LE: Non-Discoverable Mode
 				(C.1)
-TSPC_GAP_42_2	False		Peripheral BR/EDR/LE: Discoverable Mode
+TSPC_GAP_43_2	False		Peripheral BR/EDR/LE: Discoverable Mode
 				(C.2)
-TSPC_GAP_42_3	False		Peripheral BR/EDR/LE: Non-Connectable Mode
+TSPC_GAP_43_3	False		Peripheral BR/EDR/LE: Non-Connectable Mode
 				(C.3)
-TSPC_GAP_42_4	False (*)	Peripheral BR/EDR/LE: Connectable Mode  (M)
-TSPC_GAP_42_5	False		Peripheral BR/EDR/LE: Non-Bondable Mode (C.4)
-TSPC_GAP_42_6	False		Peripheral BR/EDR/LE: Bondable Mode (C.5)
+TSPC_GAP_43_4	False (*)	Peripheral BR/EDR/LE: Connectable Mode  (M)
+TSPC_GAP_43_5	False		Peripheral BR/EDR/LE: Non-Bondable Mode (C.4)
+TSPC_GAP_43_6	False		Peripheral BR/EDR/LE: Bondable Mode (C.5)
 -------------------------------------------------------------------------------
 C.1: Mandatory if TSPC_GAP_1_1 is supported over BR/EDR, otherwise Excluded.
 C.2: Mandatory if (TSPC_GAP_1_2 or TSPC_GAP_1_3) is supported over BR/EDR,
@@ -695,7 +711,21 @@ C.5: Mandatory if TSPC_GAP_1_7 is supported over BR/EDR, otherwise Excluded.
 -------------------------------------------------------------------------------
 Parameter Name	Selected	Description
 -------------------------------------------------------------------------------
-TSPC_GAP_43_1	False (*)	Peripheral BR/EDR/LE: Security Aspects (M)
+TSPC_GAP_44_1	False (*)	Peripheral BR/EDR/LE: Security Aspects (M)
+-------------------------------------------------------------------------------
+
+
+		Peripheral Simultaneous BR/EDR and LE Transports
+-------------------------------------------------------------------------------
+Parameter Name	Selected	Description
+-------------------------------------------------------------------------------
+TSPC_GAP_45_1	False		Simultaneous BR/EDR and LE Transports – BR/EDR
+					Slave to the same device (C.1)
+TSPC_GAP_45_2	False		Simultaneous BR/EDR and LE Transports – BR/EDR
+					Master to the same device (C.1)
+-------------------------------------------------------------------------------
+C.1: Optional if ((SUM ICS 31/14 (Core Spec Version 4.1) or SUM ICS 31/15
+(Core Spec Version 4.1+HS)) is supported, otherwise Excluded.
 -------------------------------------------------------------------------------
 
 
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH] android/pics: Update PICS to PTS 5.0 for DID
From: Sebastian Chlad @ 2014-01-08 10:01 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Sebastian Chlad

Remove PICS settings which are not applicable in PTS
---
 android/pics-did.txt | 12 ++----------
 1 file changed, 2 insertions(+), 10 deletions(-)

diff --git a/android/pics-did.txt b/android/pics-did.txt
index 8f92bc1..58cee41 100644
--- a/android/pics-did.txt
+++ b/android/pics-did.txt
@@ -1,21 +1,13 @@
 DID PICS for the PTS tool.
 
+PTS version: 5.0
+
 * - different than PTS defaults
 # - not yet implemented/supported
 
 M - mandatory
 O - optional
 
-		Version
--------------------------------------------------------------------------------
-Parameter Name	Selected	Description
--------------------------------------------------------------------------------
-TSPC_DID_0_1	False		Device ID 1.2 (C.1)
-TSPC_DID_0_2	True		Device ID 1.3 (C.1)
--------------------------------------------------------------------------------
-C.1: It is mandatory to support one of the profile versions.
--------------------------------------------------------------------------------
-
 
 		SDP Requirements
 -------------------------------------------------------------------------------
-- 
1.8.3.2


^ permalink raw reply related

* Re: [PATCH] android: Cleanup Android.mk
From: Szymon Janc @ 2014-01-08 10:19 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1389108453-19758-1-git-send-email-szymon.janc@tieto.com>

On Tuesday 07 of January 2014 16:27:33 Szymon Janc wrote:
> Remove not needed headers file in source list (Android build handles
> this), explicitly mark packages as optional and fix bluetooth.default
> dependencies (it should not depend on haltest as it is optional debug
> package and should not be installed in user build).
> ---
>  android/Android.mk | 30 +++++++-----------------------
>  1 file changed, 7 insertions(+), 23 deletions(-)
> 
> diff --git a/android/Android.mk b/android/Android.mk
> index 27631cc..16339b1 100644
> --- a/android/Android.mk
> +++ b/android/Android.mk
> @@ -25,8 +25,8 @@ LOCAL_SRC_FILES := \
>  	bluetooth.c \
>  	hidhost.c \
>  	socket.c \
> -	ipc.c ipc.h \
> -	audio-ipc.c audio-ipc.h \
> +	ipc.c \
> +	audio-ipc.c \
>  	avdtp.c \
>  	a2dp.c \
>  	pan.c \
> @@ -75,6 +75,8 @@ $(shell mkdir -p $(LOCAL_PATH)/../lib/bluetooth)
>  
>  $(foreach file,$(lib_headers), $(shell ln -sf ../$(file) $(LOCAL_PATH)/../lib/bluetooth/$(file)))
>  
> +LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
> +LOCAL_MODULE_TAGS := optional
>  LOCAL_MODULE := bluetoothd
>  
>  include $(BUILD_EXECUTABLE)
> @@ -107,7 +109,7 @@ LOCAL_MODULE := bluetooth.default
>  LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
>  LOCAL_MODULE_TAGS := optional
>  LOCAL_MODULE_CLASS := SHARED_LIBRARIES
> -LOCAL_REQUIRED_MODULES := haltest bluetoothd
> +LOCAL_REQUIRED_MODULES := bluetoothd bluetoothd-snoop
>  
>  include $(BUILD_SHARED_LIBRARY)
>  
> @@ -146,7 +148,8 @@ LOCAL_CFLAGS := $(BLUEZ_COMMON_CFLAGS)
>  
>  LOCAL_SHARED_LIBRARIES := libhardware
>  
> -LOCAL_MODULE_TAGS := optional
> +LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
> +LOCAL_MODULE_TAGS := debug
>  LOCAL_MODULE := haltest
>  
>  include $(BUILD_EXECUTABLE)
> @@ -159,42 +162,23 @@ include $(CLEAR_VARS)
>  
>  LOCAL_SRC_FILES := \
>  	../monitor/main.c \
> -	../monitor/bt.h \
> -	../monitor/mainloop.h \
>  	../monitor/mainloop.c \
> -	../monitor/display.h \
>  	../monitor/display.c \
> -	../monitor/hcidump.h \
>  	../monitor/hcidump.c \
> -	../monitor/btsnoop.h \
>  	../monitor/btsnoop.c \
> -	../monitor/control.h \
>  	../monitor/control.c \
> -	../monitor/packet.h \
>  	../monitor/packet.c \
> -	../monitor/l2cap.h \
>  	../monitor/l2cap.c \
> -	../monitor/uuid.h \
>  	../monitor/uuid.c \
> -	../monitor/sdp.h \
>  	../monitor/sdp.c \
> -	../monitor/vendor.h \
>  	../monitor/vendor.c \
> -	../monitor/lmp.h \
>  	../monitor/lmp.c \
> -	../monitor/crc.h \
>  	../monitor/crc.c \
> -	../monitor/ll.h \
>  	../monitor/ll.c \
> -	../monitor/hwdb.h \
>  	../monitor/hwdb.c \
> -	../monitor/ellisys.h \
>  	../monitor/ellisys.c \
> -	../monitor/analyze.h \
>  	../monitor/analyze.c \
> -	../src/shared/util.h \
>  	../src/shared/util.c \
> -	../src/shared/queue.h \
>  	../src/shared/queue.c \
>  	../lib/hci.c \
>  	../lib/bluetooth.c \
> 

Pushed upstream.

-- 
BR
Szymon Janc


^ permalink raw reply

* [PATCH_v2] android-tester: Add HIDHost initial interface setup test
From: Ravi kumar Veeramally @ 2014-01-08 11:02 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Ravi kumar Veeramally

---
 android/android-tester.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 53 insertions(+)

diff --git a/android/android-tester.c b/android/android-tester.c
index 9a161ad..cbb827d 100644
--- a/android/android-tester.c
+++ b/android/android-tester.c
@@ -39,6 +39,7 @@
 #include <hardware/hardware.h>
 #include <hardware/bluetooth.h>
 #include <hardware/bt_sock.h>
+#include <hardware/bt_hh.h>
 
 #include "utils.h"
 
@@ -79,6 +80,7 @@ struct test_data {
 	struct hw_device_t *device;
 	const bt_interface_t *if_bluetooth;
 	const btsock_interface_t *if_sock;
+	const bthh_interface_t *if_hid;
 
 	bool mgmt_settings_set;
 	bool cb_count_checked;
@@ -958,6 +960,16 @@ static bt_callbacks_t bt_callbacks = {
 	.le_test_mode_cb = NULL
 };
 
+static bthh_callbacks_t bthh_callbacks = {
+	.size = sizeof(bthh_callbacks),
+	.connection_state_cb = NULL,
+	.hid_info_cb = NULL,
+	.protocol_mode_cb = NULL,
+	.idle_time_cb = NULL,
+	.get_report_cb = NULL,
+	.virtual_unplug_cb = NULL
+};
+
 static void setup(struct test_data *data)
 {
 	const hw_module_t *module;
@@ -1069,6 +1081,11 @@ static void teardown(const void *test_data)
 		data->if_bluetooth = NULL;
 	}
 
+	if (data->if_hid) {
+		data->if_hid->cleanup();
+		data->if_hid = NULL;
+	}
+
 	data->device->close(data->device);
 
 	if (data->bluetoothd_pid)
@@ -1860,6 +1877,39 @@ clean:
 		close(sock_fd);
 }
 
+static void setup_hidhost_interface(const void *test_data)
+{
+	struct test_data *data = tester_get_data();
+	bt_status_t status;
+	const void *hid;
+
+	setup(data);
+
+	status = data->if_bluetooth->init(&bt_callbacks);
+	if (status != BT_STATUS_SUCCESS) {
+		data->if_bluetooth = NULL;
+		tester_setup_failed();
+		return;
+	}
+
+	hid = data->if_bluetooth->get_profile_interface(BT_PROFILE_HIDHOST_ID);
+	if (!hid) {
+		tester_setup_failed();
+		return;
+	}
+
+	data->if_hid = hid;
+
+	status = data->if_hid->init(&bthh_callbacks);
+	if (status != BT_STATUS_SUCCESS) {
+		data->if_hid = NULL;
+		tester_setup_failed();
+		return;
+	}
+
+	tester_setup_complete();
+}
+
 #define test_bredrle(name, data, test_setup, test, test_teardown) \
 	do { \
 		struct test_data *user; \
@@ -2071,5 +2121,8 @@ int main(int argc, char *argv[])
 			setup_socket_interface_enabled,
 			test_socket_real_connect, teardown);
 
+	test_bredrle("HIDHost Init", NULL, setup_hidhost_interface,
+						test_dummy, teardown);
+
 	return tester_run();
 }
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH] android/pics: Update PICS to PTS 5.0
From: Sebastian Chlad @ 2014-01-08 11:36 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Sebastian Chlad

Update PICS settings for HID, L2CAP, OPP, PAN and PBAP
---
 android/pics-hid.txt   | 2 ++
 android/pics-l2cap.txt | 2 ++
 android/pics-opp.txt   | 2 ++
 android/pics-pan.txt   | 2 ++
 android/pics-pbap.txt  | 5 +++--
 5 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/android/pics-hid.txt b/android/pics-hid.txt
index b0b7d52..ac37e45 100644
--- a/android/pics-hid.txt
+++ b/android/pics-hid.txt
@@ -1,5 +1,7 @@
 HID PICS for the PTS tool.
 
+PTS version: 5.0
+
 * - different than PTS defaults
 # - not yet implemented/supported
 
diff --git a/android/pics-l2cap.txt b/android/pics-l2cap.txt
index ef25133..7b49627 100644
--- a/android/pics-l2cap.txt
+++ b/android/pics-l2cap.txt
@@ -1,5 +1,7 @@
 L2CAP PICS for the PTS tool.
 
+PTS version: 5.0
+
 * - different than PTS defaults
 # - not yet implemented/supported
 
diff --git a/android/pics-opp.txt b/android/pics-opp.txt
index c0f2ad6..cd4acce 100644
--- a/android/pics-opp.txt
+++ b/android/pics-opp.txt
@@ -1,5 +1,7 @@
 OPP PICS for the PTS tool.
 
+PTS version: 5.0
+
 * - different than PTS defaults
 # - not yet implemented/supported
 
diff --git a/android/pics-pan.txt b/android/pics-pan.txt
index 7576d2d..16457bf 100644
--- a/android/pics-pan.txt
+++ b/android/pics-pan.txt
@@ -1,5 +1,7 @@
 PAN PICS for the PTS tool.
 
+PTS version: 5.0
+
 * - different than PTS defaults
 # - not yet implemented/supported
 
diff --git a/android/pics-pbap.txt b/android/pics-pbap.txt
index 7b2d7d2..b6b6d8b 100644
--- a/android/pics-pbap.txt
+++ b/android/pics-pbap.txt
@@ -1,5 +1,7 @@
 PBAP PICS for the PTS tool.
 
+PTS version: 5.0
+
 * - different than PTS defaults
 # - not yet implemented/supported
 
@@ -12,8 +14,7 @@ Parameter Name	Selected	Description
 -------------------------------------------------------------------------------
 TSPC_PBAP_0_1	False		Role: PBAP 1.0 (C.1)
 TSPC_PBAP_0_2	True (*)	Role: PBAP 1.1 (C.1)
-TSPC_PBAP_0_3	False		Role: Reserve
-TSPC_PBAP_0_4	False (*)	Role: PBAP 1.2 (C.1)
+TSPC_PBAP_0_3	False (*)	Role: PBAP 1.2 (C.1)
 -------------------------------------------------------------------------------
 C.1: Mandatory to support one and only one major profile version.
 -------------------------------------------------------------------------------
-- 
1.8.3.2

---------------------------------------------------------------------
Intel Finland Oy
Registered Address: PL 281, 00181 Helsinki 
Business Identity Code: 0357606 - 4 
Domiciled in Helsinki 

This e-mail and any attachments may contain confidential material for
the sole use of the intended recipient(s). Any review or distribution
by others is strictly prohibited. If you are not the intended
recipient, please contact the sender and delete all copies.


^ permalink raw reply related

* [PATCH_v4 0/4] Add support for NAP role
From: Ravi kumar Veeramally @ 2014-01-08 11:46 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Ravi kumar Veeramally

v4: Fixed Szymon's and Luiz's comments.

v3: Fixed Johan's comments (removed fopen, fprintf and used open and write).

v2: Fixed Johan's comments.

v1: This patch set add support for NAP role. It register NAP server and create
  bnep bridge and listen for incoming connections from client devices.
  On incoming connection request it accepts connection, creates bnep interface
  and notifies control state and connection state infromation. Removes device
  on disconnect request. Android related changes are required to enable this
  role. Patches sent to respective ML.

Ravi kumar Veeramally (4):
  android/pan: Register Network Access Point
  android/pan: Listen for incoming connections and accept in NAP role
  android/pan: Implement PAN enable HAL api at daemon side
  android/pan: Remove connected PAN devices on profile unregister call

 android/pan.c | 346 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 334 insertions(+), 12 deletions(-)

-- 
1.8.3.2


^ permalink raw reply

* [PATCH_v4 1/4] android/pan: Register Network Access Point
From: Ravi kumar Veeramally @ 2014-01-08 11:46 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Ravi kumar Veeramally
In-Reply-To: <1389181593-9683-1-git-send-email-ravikumar.veeramally@linux.intel.com>

Register NAP server and adds bnep bridge. Removes bridge
on destroy call. Bridge mechanism is needed when device acting
as a server and listen for incoming connections.
---
 android/pan.c | 111 +++++++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 107 insertions(+), 4 deletions(-)

diff --git a/android/pan.c b/android/pan.c
index 38e353d..9de2b40 100644
--- a/android/pan.c
+++ b/android/pan.c
@@ -28,6 +28,11 @@
 #include <unistd.h>
 #include <fcntl.h>
 #include <glib.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <sys/wait.h>
+#include <net/if.h>
+#include <linux/sockios.h>
 
 #include "btio/btio.h"
 #include "lib/bluetooth.h"
@@ -45,11 +50,11 @@
 #include "bluetooth.h"
 
 #define SVC_HINT_NETWORKING 0x02
+#define BNEP_BRIDGE	"bnep"
 
 static bdaddr_t adapter_addr;
 GSList *devices = NULL;
 uint8_t local_role = HAL_PAN_ROLE_NONE;
-static uint32_t record_id = 0;
 
 struct pan_device {
 	char		iface[16];
@@ -60,6 +65,12 @@ struct pan_device {
 	struct bnep	*session;
 };
 
+static struct {
+	uint32_t	record_id;
+} nap_dev = {
+	.record_id = 0,
+};
+
 static int device_cmp(gconstpointer s, gconstpointer user_data)
 {
 	const struct pan_device *dev = s;
@@ -297,6 +308,89 @@ failed:
 	ipc_send_rsp(HAL_SERVICE_ID_PAN, HAL_OP_PAN_DISCONNECT, status);
 }
 
+static int set_forward_delay(void)
+{
+	int fd, ret;
+	char path[41];
+
+	sprintf(path, "/sys/class/net/%s/bridge/forward_delay", BNEP_BRIDGE);
+
+	fd = open(path, O_RDWR);
+	if (fd < 0)
+		return -errno;
+
+	ret = write(fd, "0", sizeof("0"));
+	close(fd);
+
+	return ret;
+}
+
+static int nap_create_bridge(void)
+{
+	int sk, err;
+
+	DBG("%s", BNEP_BRIDGE);
+
+	sk = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
+	if (sk < 0)
+		return -EOPNOTSUPP;
+
+	if (ioctl(sk, SIOCBRADDBR, BNEP_BRIDGE) < 0) {
+		err = -errno;
+		if (err != -EEXIST) {
+			close(sk);
+			return -EOPNOTSUPP;
+		}
+	}
+
+	err = set_forward_delay();
+	if (err < 0)
+		ioctl(sk, SIOCBRDELBR, BNEP_BRIDGE);
+
+	close(sk);
+
+	return err;
+}
+
+static int nap_remove_bridge(void)
+{
+	int sk, err;
+
+	DBG("%s", BNEP_BRIDGE);
+
+	sk = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
+	if (sk < 0)
+		return -EOPNOTSUPP;
+
+	err = ioctl(sk, SIOCBRDELBR, BNEP_BRIDGE);
+	close(sk);
+
+	if (err < 0)
+		return -EOPNOTSUPP;
+
+	return 0;
+}
+
+static void destroy_nap_device(void)
+{
+	DBG("");
+
+	nap_remove_bridge();
+}
+
+static int register_nap_server(void)
+{
+	int err;
+
+	DBG("");
+
+	err = nap_create_bridge();
+	if (err < 0)
+		return err;
+
+	return 0;
+}
+
 static void bt_pan_enable(const void *buf, uint16_t len)
 {
 	const struct hal_cmd_pan_enable *cmd = buf;
@@ -441,7 +535,15 @@ bool bt_pan_register(const bdaddr_t *addr)
 		return false;
 	}
 
-	record_id = rec->handle;
+	err = register_nap_server();
+	if (err < 0) {
+		bt_adapter_remove_record(rec->handle);
+		sdp_record_free(rec);
+		bnep_cleanup();
+		return false;
+	}
+
+	nap_dev.record_id = rec->handle;
 	ipc_register(HAL_SERVICE_ID_PAN, cmd_handlers,
 						G_N_ELEMENTS(cmd_handlers));
 
@@ -455,6 +557,7 @@ void bt_pan_unregister(void)
 	bnep_cleanup();
 
 	ipc_unregister(HAL_SERVICE_ID_PAN);
-	bt_adapter_remove_record(record_id);
-	record_id = 0;
+	bt_adapter_remove_record(nap_dev.record_id);
+	nap_dev.record_id = 0;
+	destroy_nap_device();
 }
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH_v4 2/4] android/pan: Listen for incoming connections and accept in NAP role
From: Ravi kumar Veeramally @ 2014-01-08 11:46 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Ravi kumar Veeramally
In-Reply-To: <1389181593-9683-1-git-send-email-ravikumar.veeramally@linux.intel.com>

Listen for incoming connections and accept it. Create bnep interface
add it to bridge and notify control and connection state information
through HAL. Remove the device on disconnect request. If android
settings UI does not have bluetooth tethering enabled it immediately
sends disconnect signal.
---
 android/pan.c | 192 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 189 insertions(+), 3 deletions(-)

diff --git a/android/pan.c b/android/pan.c
index 9de2b40..61c34f3 100644
--- a/android/pan.c
+++ b/android/pan.c
@@ -63,12 +63,17 @@ struct pan_device {
 	uint8_t		role;
 	GIOChannel	*io;
 	struct bnep	*session;
+	guint		watch;
 };
 
 static struct {
 	uint32_t	record_id;
+	guint		watch;
+	GIOChannel	*io;
 } nap_dev = {
 	.record_id = 0,
+	.watch = 0,
+	.io = NULL,
 };
 
 static int device_cmp(gconstpointer s, gconstpointer user_data)
@@ -81,13 +86,19 @@ static int device_cmp(gconstpointer s, gconstpointer user_data)
 
 static void pan_device_free(struct pan_device *dev)
 {
+	if (dev->watch > 0) {
+		bnep_server_delete(BNEP_BRIDGE, dev->iface, &dev->dst);
+		g_source_remove(dev->watch);
+	}
+
 	if (dev->io) {
 		g_io_channel_shutdown(dev->io, FALSE, NULL);
 		g_io_channel_unref(dev->io);
-		dev->io = NULL;
 	}
 
-	bnep_free(dev->session);
+	if (dev->session)
+		bnep_free(dev->session);
+
 	devices = g_slist_remove(devices, dev);
 	g_free(dev);
 
@@ -298,7 +309,7 @@ static void bt_pan_disconnect(const void *buf, uint16_t len)
 
 	dev = l->data;
 
-	if (dev->conn_state == HAL_PAN_STATE_CONNECTED)
+	if (dev->conn_state == HAL_PAN_STATE_CONNECTED && dev->session)
 		bnep_disconnect(dev->session);
 
 	bt_pan_notify_conn_state(dev, HAL_PAN_STATE_DISCONNECTED);
@@ -308,6 +319,154 @@ failed:
 	ipc_send_rsp(HAL_SERVICE_ID_PAN, HAL_OP_PAN_DISCONNECT, status);
 }
 
+static gboolean nap_watchdog_cb(GIOChannel *chan, GIOCondition cond,
+							gpointer user_data)
+{
+	struct pan_device *dev = user_data;
+
+	DBG("disconnected");
+
+	bt_pan_notify_conn_state(dev, HAL_PAN_STATE_DISCONNECTED);
+
+	return FALSE;
+}
+static gboolean nap_setup_cb(GIOChannel *chan, GIOCondition cond,
+							gpointer user_data)
+{
+	struct pan_device *dev = user_data;
+	uint8_t packet[BNEP_MTU];
+	struct bnep_setup_conn_req *req = (void *) packet;
+	uint16_t src_role, dst_role, rsp = BNEP_CONN_NOT_ALLOWED;
+	int sk, n;
+
+	if (cond & (G_IO_ERR | G_IO_HUP | G_IO_NVAL)) {
+		error("Hangup or error or inval on BNEP socket");
+		return FALSE;
+	}
+
+	sk = g_io_channel_unix_get_fd(chan);
+
+	/* Reading BNEP_SETUP_CONNECTION_REQUEST_MSG */
+	n = read(sk, packet, sizeof(packet));
+	if (n  < 0) {
+		error("read(): %s(%d)", strerror(errno), errno);
+		goto failed;
+	}
+
+	/* Highest known control command id BNEP_FILTER_MULT_ADDR_RSP 0x06 */
+	if (req->type == BNEP_CONTROL &&
+			req->ctrl > BNEP_FILTER_MULT_ADDR_RSP) {
+		error("cmd not understood");
+		bnep_send_ctrl_rsp(sk, BNEP_CONTROL, BNEP_CMD_NOT_UNDERSTOOD,
+								req->ctrl);
+		goto failed;
+	}
+
+	if (req->type != BNEP_CONTROL || req->ctrl != BNEP_SETUP_CONN_REQ) {
+		error("cmd is not BNEP_SETUP_CONN_REQ %02X %02X", req->type,
+								req->ctrl);
+		goto failed;
+	}
+
+	rsp = bnep_setup_decode(req, &dst_role, &src_role);
+	if (rsp) {
+		error("bnep_setup_decode failed");
+		goto failed;
+	}
+
+	rsp = bnep_setup_chk(dst_role, src_role);
+	if (rsp) {
+		error("benp_setup_chk failed");
+		goto failed;
+	}
+
+	if (bnep_server_add(sk, dst_role, BNEP_BRIDGE, dev->iface,
+							&dev->dst) < 0) {
+		error("server_connadd failed");
+		rsp = BNEP_CONN_NOT_ALLOWED;
+		goto failed;
+	}
+
+	rsp = BNEP_SUCCESS;
+	bnep_send_ctrl_rsp(sk, BNEP_CONTROL, BNEP_SETUP_CONN_RSP, rsp);
+
+	dev->watch = g_io_add_watch(chan, G_IO_HUP | G_IO_ERR | G_IO_NVAL,
+							nap_watchdog_cb, dev);
+	g_io_channel_unref(dev->io);
+	dev->io = NULL;
+
+	bt_pan_notify_ctrl_state(dev, HAL_PAN_CTRL_ENABLED);
+	bt_pan_notify_conn_state(dev, HAL_PAN_STATE_CONNECTED);
+
+	return FALSE;
+
+failed:
+	bnep_send_ctrl_rsp(sk, BNEP_CONTROL, BNEP_SETUP_CONN_RSP, rsp);
+	pan_device_free(dev);
+
+	return FALSE;
+}
+
+static void nap_connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
+{
+	struct pan_device *dev = user_data;
+
+	DBG("");
+
+	if (err) {
+		error("%s", err->message);
+		bt_pan_notify_conn_state(dev, HAL_PAN_STATE_DISCONNECTED);
+		return;
+	}
+
+	g_io_channel_set_close_on_unref(chan, TRUE);
+	dev->watch = g_io_add_watch(chan,
+				G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
+				nap_setup_cb, dev);
+}
+
+static void nap_confirm_cb(GIOChannel *chan, gpointer data)
+{
+	struct pan_device *dev = NULL;
+	bdaddr_t dst;
+	char address[18];
+	GError *err = NULL;
+
+	DBG("");
+
+	bt_io_get(chan, &err, BT_IO_OPT_DEST_BDADDR, &dst,
+			BT_IO_OPT_DEST, address, BT_IO_OPT_INVALID);
+	if (err) {
+		error("%s", err->message);
+		g_error_free(err);
+		goto failed;
+	}
+
+	DBG("incoming connect request from %s", address);
+	dev = g_new0(struct pan_device, 1);
+	bacpy(&dev->dst, &dst);
+	local_role = HAL_PAN_ROLE_NAP;
+	dev->role = HAL_PAN_ROLE_PANU;
+
+	dev->io = g_io_channel_ref(chan);
+	g_io_channel_set_close_on_unref(dev->io, TRUE);
+
+	if (!bt_io_accept(dev->io, nap_connect_cb, dev, NULL, &err)) {
+		error("bt_io_accept: %s", err->message);
+		g_error_free(err);
+		goto failed;
+	}
+
+	devices = g_slist_append(devices, dev);
+	bt_pan_notify_conn_state(dev, HAL_PAN_STATE_CONNECTING);
+
+	return;
+
+failed:
+	g_free(dev);
+	bt_pan_notify_conn_state(dev, HAL_PAN_STATE_DISCONNECTED);
+}
+
 static int set_forward_delay(void)
 {
 	int fd, ret;
@@ -376,10 +535,22 @@ static void destroy_nap_device(void)
 	DBG("");
 
 	nap_remove_bridge();
+
+	if (nap_dev.watch > 0) {
+		g_source_remove(nap_dev.watch);
+		nap_dev.watch = 0;
+	}
+
+	if (nap_dev.io) {
+		g_io_channel_shutdown(nap_dev.io, FALSE, NULL);
+		g_io_channel_unref(nap_dev.io);
+		nap_dev.io = NULL;
+	}
 }
 
 static int register_nap_server(void)
 {
+	GError *gerr;
 	int err;
 
 	DBG("");
@@ -388,6 +559,21 @@ static int register_nap_server(void)
 	if (err < 0)
 		return err;
 
+	nap_dev.io = bt_io_listen(NULL, nap_confirm_cb, NULL, NULL, &gerr,
+					BT_IO_OPT_SOURCE_BDADDR, &adapter_addr,
+					BT_IO_OPT_PSM, BNEP_PSM,
+					BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
+					BT_IO_OPT_OMTU, BNEP_MTU,
+					BT_IO_OPT_IMTU, BNEP_MTU,
+					BT_IO_OPT_INVALID);
+
+	if (!nap_dev.io) {
+		destroy_nap_device();
+		error("%s", gerr->message);
+		g_error_free(gerr);
+		return -EINVAL;
+	}
+
 	return 0;
 }
 
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH_v4 3/4] android/pan: Implement PAN enable HAL api at daemon side
From: Ravi kumar Veeramally @ 2014-01-08 11:46 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Ravi kumar Veeramally
In-Reply-To: <1389181593-9683-1-git-send-email-ravikumar.veeramally@linux.intel.com>

---
 android/pan.c | 33 ++++++++++++++++++++++++++++-----
 1 file changed, 28 insertions(+), 5 deletions(-)

diff --git a/android/pan.c b/android/pan.c
index 61c34f3..d5ae690 100644
--- a/android/pan.c
+++ b/android/pan.c
@@ -581,18 +581,41 @@ static void bt_pan_enable(const void *buf, uint16_t len)
 {
 	const struct hal_cmd_pan_enable *cmd = buf;
 	uint8_t status;
+	int err;
+
+	DBG("");
+
+	if (local_role == cmd->local_role) {
+		status = HAL_STATUS_SUCCESS;
+		goto reply;
+	}
+
+	/* destroy existing server */
+	destroy_nap_device();
 
 	switch (cmd->local_role) {
 	case HAL_PAN_ROLE_PANU:
-	case HAL_PAN_ROLE_NAP:
-		DBG("Not Implemented");
-		status  = HAL_STATUS_FAILED;
-		break;
+		status = HAL_STATUS_UNSUPPORTED;
+		goto reply;
+	case HAL_PAN_ROLE_NONE:
+		status = HAL_STATUS_SUCCESS;
+		goto reply;
 	default:
 		status = HAL_STATUS_UNSUPPORTED;
-		break;
+		goto reply;
+	}
+
+	local_role = cmd->local_role;
+	err = register_nap_server();
+	if (err < 0) {
+		status = HAL_STATUS_FAILED;
+		destroy_nap_device();
+		goto reply;
 	}
 
+	status = HAL_STATUS_SUCCESS;
+
+reply:
 	ipc_send_rsp(HAL_SERVICE_ID_PAN, HAL_OP_PAN_ENABLE, status);
 }
 
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH_v4 4/4] android/pan: Remove connected PAN devices on profile unregister call
From: Ravi kumar Veeramally @ 2014-01-08 11:46 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Ravi kumar Veeramally
In-Reply-To: <1389181593-9683-1-git-send-email-ravikumar.veeramally@linux.intel.com>

---
 android/pan.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/android/pan.c b/android/pan.c
index d5ae690..621dc62 100644
--- a/android/pan.c
+++ b/android/pan.c
@@ -759,10 +759,20 @@ bool bt_pan_register(const bdaddr_t *addr)
 	return true;
 }
 
+static void pan_device_disconnected(gpointer data, gpointer user_data)
+{
+	struct pan_device *dev = data;
+
+	bt_pan_notify_conn_state(dev, HAL_PAN_STATE_DISCONNECTED);
+}
+
 void bt_pan_unregister(void)
 {
 	DBG("");
 
+	g_slist_foreach(devices, pan_device_disconnected, NULL);
+	devices = NULL;
+
 	bnep_cleanup();
 
 	ipc_unregister(HAL_SERVICE_ID_PAN);
-- 
1.8.3.2


^ permalink raw reply related

* Re: [PATCH v3 1/3] android: Add wrapper function for get remote dev properties
From: Szymon Janc @ 2014-01-08 12:19 UTC (permalink / raw)
  To: Lukasz Rymanowski; +Cc: linux-bluetooth, johan.hedberg
In-Reply-To: <1389104030-21314-1-git-send-email-lukasz.rymanowski@tieto.com>

Hi Łukasz,

> ---
>  android/bluetooth.c | 23 ++++++++++++++---------
>  1 file changed, 14 insertions(+), 9 deletions(-)
> 
> diff --git a/android/bluetooth.c b/android/bluetooth.c
> index 3cbf68d..f281fcf 100644
> --- a/android/bluetooth.c
> +++ b/android/bluetooth.c
> @@ -2673,6 +2673,19 @@ static uint8_t get_device_timestamp(struct device *dev)
>  	return HAL_STATUS_SUCCESS;
>  }
>  
> +static void get_remote_device_props(struct device *dev)
> +{
> +	get_device_name(dev);
> +	get_device_uuids(dev);
> +	get_device_class(dev);
> +	get_device_type(dev);
> +	get_device_service_rec(dev);
> +	get_device_friendly_name(dev);
> +	get_device_rssi(dev);
> +	get_device_version_info(dev);
> +	get_device_timestamp(dev);
> +}
> +
>  static void handle_get_remote_device_props_cmd(const void *buf, uint16_t len)
>  {
>  	const struct hal_cmd_get_remote_device_props *cmd = buf;
> @@ -2688,15 +2701,7 @@ static void handle_get_remote_device_props_cmd(const void *buf, uint16_t len)
>  		goto failed;
>  	}
>  
> -	get_device_name(l->data);
> -	get_device_uuids(l->data);
> -	get_device_class(l->data);
> -	get_device_type(l->data);
> -	get_device_service_rec(l->data);
> -	get_device_friendly_name(l->data);
> -	get_device_rssi(l->data);
> -	get_device_version_info(l->data);
> -	get_device_timestamp(l->data);
> +	get_remote_device_props(l->data);
>  
>  	status = HAL_STATUS_SUCCESS;
>  
> 

Patches applied, thanks.

-- 
BR
Szymon Janc

^ permalink raw reply

* Re: [PATCH] android/pics: Update PICS to PTS 5.0 for GAP
From: Szymon Janc @ 2014-01-08 13:19 UTC (permalink / raw)
  To: Sebastian Chlad; +Cc: linux-bluetooth
In-Reply-To: <1389174407-28486-1-git-send-email-sebastianx.chlad@intel.com>

Hi Sebastian,

> Add new PICS settings for the GAP profile in accordance with PTS 5.0
> ---
>  android/pics-gap.txt | 44 +++++++++++++++++++++++++++++++++++++-------
>  1 file changed, 37 insertions(+), 7 deletions(-)
> 
> diff --git a/android/pics-gap.txt b/android/pics-gap.txt
> index e8ab2ab..56a33d5 100644
> --- a/android/pics-gap.txt
> +++ b/android/pics-gap.txt
> @@ -1,5 +1,7 @@
>  GAP PICS for the PTS tool.
>  
> +PTS version: 5.0
> +
>  * - different than PTS defaults
>  # - not yet implemented/supported
>  
> @@ -668,19 +670,33 @@ TSPC_GAP_41_1	True (#)	Central BR/EDR/LE: Security Aspects (M)
>  -------------------------------------------------------------------------------
>  
>  
> +		Central Simultaneous BR/EDR and LE Transports
> +-------------------------------------------------------------------------------
> +Parameter Name	Selected	Description
> +-------------------------------------------------------------------------------
> +TSPC_GAP_42_1	False		Simultaneous BR/EDR and LE Transports –	BR/EDR
> +					Slave to the same device (C.1)
> +TSPC_GAP_42_2	False		Simultaneous BR/EDR and LE Transports – BR/EDR
> +					Master to the same device (C.1)
> +-------------------------------------------------------------------------------
> +C.1: Optional if ((SUM ICS 31/14 (Core Spec Version 4.1) or SUM ICS 31/15
> +	(Core Spec Version 4.1+HS)) is supported, otherwise Excluded.
> +-------------------------------------------------------------------------------
> +
> +
>  		Peripheral BR/EDR/LE Modes
>  -------------------------------------------------------------------------------
>  Parameter Name	Selected	Description
>  -------------------------------------------------------------------------------
> -TSPC_GAP_42_1	False		Peripheral BR/EDR/LE: Non-Discoverable Mode
> +TSPC_GAP_43_1	False		Peripheral BR/EDR/LE: Non-Discoverable Mode
>  				(C.1)
> -TSPC_GAP_42_2	False		Peripheral BR/EDR/LE: Discoverable Mode
> +TSPC_GAP_43_2	False		Peripheral BR/EDR/LE: Discoverable Mode
>  				(C.2)
> -TSPC_GAP_42_3	False		Peripheral BR/EDR/LE: Non-Connectable Mode
> +TSPC_GAP_43_3	False		Peripheral BR/EDR/LE: Non-Connectable Mode
>  				(C.3)
> -TSPC_GAP_42_4	False (*)	Peripheral BR/EDR/LE: Connectable Mode  (M)
> -TSPC_GAP_42_5	False		Peripheral BR/EDR/LE: Non-Bondable Mode (C.4)
> -TSPC_GAP_42_6	False		Peripheral BR/EDR/LE: Bondable Mode (C.5)
> +TSPC_GAP_43_4	False (*)	Peripheral BR/EDR/LE: Connectable Mode  (M)
> +TSPC_GAP_43_5	False		Peripheral BR/EDR/LE: Non-Bondable Mode (C.4)
> +TSPC_GAP_43_6	False		Peripheral BR/EDR/LE: Bondable Mode (C.5)
>  -------------------------------------------------------------------------------
>  C.1: Mandatory if TSPC_GAP_1_1 is supported over BR/EDR, otherwise Excluded.
>  C.2: Mandatory if (TSPC_GAP_1_2 or TSPC_GAP_1_3) is supported over BR/EDR,
> @@ -695,7 +711,21 @@ C.5: Mandatory if TSPC_GAP_1_7 is supported over BR/EDR, otherwise Excluded.
>  -------------------------------------------------------------------------------
>  Parameter Name	Selected	Description
>  -------------------------------------------------------------------------------
> -TSPC_GAP_43_1	False (*)	Peripheral BR/EDR/LE: Security Aspects (M)
> +TSPC_GAP_44_1	False (*)	Peripheral BR/EDR/LE: Security Aspects (M)
> +-------------------------------------------------------------------------------
> +
> +
> +		Peripheral Simultaneous BR/EDR and LE Transports
> +-------------------------------------------------------------------------------
> +Parameter Name	Selected	Description
> +-------------------------------------------------------------------------------
> +TSPC_GAP_45_1	False		Simultaneous BR/EDR and LE Transports – BR/EDR
> +					Slave to the same device (C.1)
> +TSPC_GAP_45_2	False		Simultaneous BR/EDR and LE Transports – BR/EDR
> +					Master to the same device (C.1)
> +-------------------------------------------------------------------------------
> +C.1: Optional if ((SUM ICS 31/14 (Core Spec Version 4.1) or SUM ICS 31/15
> +(Core Spec Version 4.1+HS)) is supported, otherwise Excluded.
>  -------------------------------------------------------------------------------
>  
>  
> 

Applied, thanks.

-- 
BR
Szymon Janc


^ permalink raw reply

* Re: [PATCH] android/pics: Update PICS to PTS 5.0 for DID
From: Szymon Janc @ 2014-01-08 13:19 UTC (permalink / raw)
  To: Sebastian Chlad; +Cc: linux-bluetooth
In-Reply-To: <1389175277-28726-1-git-send-email-sebastianx.chlad@intel.com>

Hi Sebastian,

> Remove PICS settings which are not applicable in PTS
> ---
>  android/pics-did.txt | 12 ++----------
>  1 file changed, 2 insertions(+), 10 deletions(-)
> 
> diff --git a/android/pics-did.txt b/android/pics-did.txt
> index 8f92bc1..58cee41 100644
> --- a/android/pics-did.txt
> +++ b/android/pics-did.txt
> @@ -1,21 +1,13 @@
>  DID PICS for the PTS tool.
>  
> +PTS version: 5.0
> +
>  * - different than PTS defaults
>  # - not yet implemented/supported
>  
>  M - mandatory
>  O - optional
>  
> -		Version
> --------------------------------------------------------------------------------
> -Parameter Name	Selected	Description
> --------------------------------------------------------------------------------
> -TSPC_DID_0_1	False		Device ID 1.2 (C.1)
> -TSPC_DID_0_2	True		Device ID 1.3 (C.1)
> --------------------------------------------------------------------------------
> -C.1: It is mandatory to support one of the profile versions.
> --------------------------------------------------------------------------------
> -
>  
>  		SDP Requirements
>  -------------------------------------------------------------------------------
> 

Applied, thanks.

-- 
BR
Szymon Janc

^ permalink raw reply

* Re: [PATCH] android/pics: Update PICS to PTS 5.0
From: Szymon Janc @ 2014-01-08 13:20 UTC (permalink / raw)
  To: Sebastian Chlad; +Cc: linux-bluetooth
In-Reply-To: <1389181018-30211-1-git-send-email-sebastianx.chlad@intel.com>

Hi Sebastian,

> Update PICS settings for HID, L2CAP, OPP, PAN and PBAP
> ---
>  android/pics-hid.txt   | 2 ++
>  android/pics-l2cap.txt | 2 ++
>  android/pics-opp.txt   | 2 ++
>  android/pics-pan.txt   | 2 ++
>  android/pics-pbap.txt  | 5 +++--
>  5 files changed, 11 insertions(+), 2 deletions(-)
> 
> diff --git a/android/pics-hid.txt b/android/pics-hid.txt
> index b0b7d52..ac37e45 100644
> --- a/android/pics-hid.txt
> +++ b/android/pics-hid.txt
> @@ -1,5 +1,7 @@
>  HID PICS for the PTS tool.
>  
> +PTS version: 5.0
> +
>  * - different than PTS defaults
>  # - not yet implemented/supported
>  
> diff --git a/android/pics-l2cap.txt b/android/pics-l2cap.txt
> index ef25133..7b49627 100644
> --- a/android/pics-l2cap.txt
> +++ b/android/pics-l2cap.txt
> @@ -1,5 +1,7 @@
>  L2CAP PICS for the PTS tool.
>  
> +PTS version: 5.0
> +
>  * - different than PTS defaults
>  # - not yet implemented/supported
>  
> diff --git a/android/pics-opp.txt b/android/pics-opp.txt
> index c0f2ad6..cd4acce 100644
> --- a/android/pics-opp.txt
> +++ b/android/pics-opp.txt
> @@ -1,5 +1,7 @@
>  OPP PICS for the PTS tool.
>  
> +PTS version: 5.0
> +
>  * - different than PTS defaults
>  # - not yet implemented/supported
>  
> diff --git a/android/pics-pan.txt b/android/pics-pan.txt
> index 7576d2d..16457bf 100644
> --- a/android/pics-pan.txt
> +++ b/android/pics-pan.txt
> @@ -1,5 +1,7 @@
>  PAN PICS for the PTS tool.
>  
> +PTS version: 5.0
> +
>  * - different than PTS defaults
>  # - not yet implemented/supported
>  
> diff --git a/android/pics-pbap.txt b/android/pics-pbap.txt
> index 7b2d7d2..b6b6d8b 100644
> --- a/android/pics-pbap.txt
> +++ b/android/pics-pbap.txt
> @@ -1,5 +1,7 @@
>  PBAP PICS for the PTS tool.
>  
> +PTS version: 5.0
> +
>  * - different than PTS defaults
>  # - not yet implemented/supported
>  
> @@ -12,8 +14,7 @@ Parameter Name	Selected	Description
>  -------------------------------------------------------------------------------
>  TSPC_PBAP_0_1	False		Role: PBAP 1.0 (C.1)
>  TSPC_PBAP_0_2	True (*)	Role: PBAP 1.1 (C.1)
> -TSPC_PBAP_0_3	False		Role: Reserve
> -TSPC_PBAP_0_4	False (*)	Role: PBAP 1.2 (C.1)
> +TSPC_PBAP_0_3	False (*)	Role: PBAP 1.2 (C.1)
>  -------------------------------------------------------------------------------
>  C.1: Mandatory to support one and only one major profile version.
>  -------------------------------------------------------------------------------
> 

Applied, thanks.

-- 
BR
Szymon Janc


^ permalink raw reply

* [PATCH 1/2] android/audio: Add wrapper stuct for audio structures
From: Lukasz Rymanowski @ 2014-01-08 13:37 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: luiz.dentz, szymon.janc, johan.hedberg, Lukasz Rymanowski

This patch add wrapping struct for audio_hw_dev and audio_stream_out.
We will need this to keep some more addition info related to a2dp stream
and also hal IPC.

---
 android/hal-audio.c | 109 +++++++++++++++++++++++++++++++---------------------
 1 file changed, 65 insertions(+), 44 deletions(-)

diff --git a/android/hal-audio.c b/android/hal-audio.c
index 7f4a3f2..bb68648 100644
--- a/android/hal-audio.c
+++ b/android/hal-audio.c
@@ -25,6 +25,15 @@
 
 #include "hal-log.h"
 
+struct a2dp_stream_out {
+	struct audio_stream_out stream;
+};
+
+struct a2dp_audio_dev {
+	struct audio_hw_device dev;
+	struct a2dp_stream_out *stream_out;
+};
+
 static ssize_t out_write(struct audio_stream_out *stream, const void *buffer,
 								size_t bytes)
 {
@@ -230,32 +239,37 @@ static int audio_open_output_stream(struct audio_hw_device *dev,
 					struct audio_stream_out **stream_out)
 
 {
-	struct audio_stream_out *out;
+	struct a2dp_audio_dev *a2dp_dev = (struct a2dp_audio_dev *)dev;
+	struct a2dp_stream_out *a2dp_out;
 
-	out = calloc(1, sizeof(struct audio_stream_out));
-	if (!out)
+	a2dp_out = calloc(1, sizeof(struct a2dp_stream_out));
+	if (!a2dp_out)
 		return -ENOMEM;
 
 	DBG("");
 
-	out->common.get_sample_rate = out_get_sample_rate;
-	out->common.set_sample_rate = out_set_sample_rate;
-	out->common.get_buffer_size = out_get_buffer_size;
-	out->common.get_channels = out_get_channels;
-	out->common.get_format = out_get_format;
-	out->common.set_format = out_set_format;
-	out->common.standby = out_standby;
-	out->common.dump = out_dump;
-	out->common.set_parameters = out_set_parameters;
-	out->common.get_parameters = out_get_parameters;
-	out->common.add_audio_effect = out_add_audio_effect;
-	out->common.remove_audio_effect = out_remove_audio_effect;
-	out->get_latency = out_get_latency;
-	out->set_volume = out_set_volume;
-	out->write = out_write;
-	out->get_render_position = out_get_render_position;
-
-	*stream_out = out;
+	a2dp_out->stream.common.get_sample_rate = out_get_sample_rate;
+	a2dp_out->stream.common.set_sample_rate = out_set_sample_rate;
+	a2dp_out->stream.common.get_buffer_size = out_get_buffer_size;
+	a2dp_out->stream.common.get_channels = out_get_channels;
+	a2dp_out->stream.common.get_format = out_get_format;
+	a2dp_out->stream.common.set_format = out_set_format;
+	a2dp_out->stream.common.standby = out_standby;
+	a2dp_out->stream.common.dump = out_dump;
+	a2dp_out->stream.common.set_parameters = out_set_parameters;
+	a2dp_out->stream.common.get_parameters = out_get_parameters;
+	a2dp_out->stream.common.add_audio_effect = out_add_audio_effect;
+	a2dp_out->stream.common.remove_audio_effect = out_remove_audio_effect;
+	a2dp_out->stream.get_latency = out_get_latency;
+	a2dp_out->stream.set_volume = out_set_volume;
+	a2dp_out->stream.write = out_write;
+	a2dp_out->stream.get_render_position = out_get_render_position;
+
+	/* Note that &a2dp_out->stream pointer is same as a2dp_out. This
+	 * results from the structure of a2dp_stream_out struct. We rely on it
+	 * later in the code */
+	*stream_out = &a2dp_out->stream;
+	a2dp_dev->stream_out = a2dp_out;
 
 	return 0;
 }
@@ -264,6 +278,10 @@ static void audio_close_output_stream(struct audio_hw_device *dev,
 					struct audio_stream_out *stream)
 {
 	DBG("");
+	struct a2dp_audio_dev *a2dp_dev = (struct a2dp_audio_dev *)dev;
+
+	free(stream);
+	a2dp_dev->stream_out = NULL;
 }
 
 static int audio_set_parameters(struct audio_hw_device *dev,
@@ -381,7 +399,7 @@ static int audio_close(hw_device_t *device)
 static int audio_open(const hw_module_t *module, const char *name,
 							hw_device_t **device)
 {
-	struct audio_hw_device *audio;
+	struct a2dp_audio_dev *a2dp_dev;
 
 	DBG("");
 
@@ -391,30 +409,33 @@ static int audio_open(const hw_module_t *module, const char *name,
 		return -EINVAL;
 	}
 
-	audio = calloc(1, sizeof(struct audio_hw_device));
-	if (!audio)
+	a2dp_dev = calloc(1, sizeof(struct a2dp_audio_dev));
+	if (!a2dp_dev)
 		return -ENOMEM;
 
-	audio->common.version = AUDIO_DEVICE_API_VERSION_CURRENT;
-	audio->common.module = (struct hw_module_t *) module;
-	audio->common.close = audio_close;
-
-	audio->init_check = audio_init_check;
-	audio->set_voice_volume = audio_set_voice_volume;
-	audio->set_master_volume = audio_set_master_volume;
-	audio->set_mode = audio_set_mode;
-	audio->set_mic_mute = audio_set_mic_mute;
-	audio->get_mic_mute = audio_get_mic_mute;
-	audio->set_parameters = audio_set_parameters;
-	audio->get_parameters = audio_get_parameters;
-	audio->get_input_buffer_size = audio_get_input_buffer_size;
-	audio->open_output_stream = audio_open_output_stream;
-	audio->close_output_stream = audio_close_output_stream;
-	audio->open_input_stream = audio_open_input_stream;
-	audio->close_input_stream = audio_close_input_stream;
-	audio->dump = audio_dump;
-
-	*device = &audio->common;
+	a2dp_dev->dev.common.version = AUDIO_DEVICE_API_VERSION_CURRENT;
+	a2dp_dev->dev.common.module = (struct hw_module_t *) module;
+	a2dp_dev->dev.common.close = audio_close;
+
+	a2dp_dev->dev.init_check = audio_init_check;
+	a2dp_dev->dev.set_voice_volume = audio_set_voice_volume;
+	a2dp_dev->dev.set_master_volume = audio_set_master_volume;
+	a2dp_dev->dev.set_mode = audio_set_mode;
+	a2dp_dev->dev.set_mic_mute = audio_set_mic_mute;
+	a2dp_dev->dev.get_mic_mute = audio_get_mic_mute;
+	a2dp_dev->dev.set_parameters = audio_set_parameters;
+	a2dp_dev->dev.get_parameters = audio_get_parameters;
+	a2dp_dev->dev.get_input_buffer_size = audio_get_input_buffer_size;
+	a2dp_dev->dev.open_output_stream = audio_open_output_stream;
+	a2dp_dev->dev.close_output_stream = audio_close_output_stream;
+	a2dp_dev->dev.open_input_stream = audio_open_input_stream;
+	a2dp_dev->dev.close_input_stream = audio_close_input_stream;
+	a2dp_dev->dev.dump = audio_dump;
+
+	/* Note that &a2dp_dev->dev.common is the same pointer as a2dp_dev.
+	 * This results from the structure of following structs:a2dp_audio_dev,
+	 * audio_hw_device. We will rely on this later in the code.*/
+	*device = &a2dp_dev->dev.common;
 
 	return 0;
 }
-- 
1.8.4


^ 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