Linux bluetooth development
 help / color / mirror / Atom feed
* [PATCHv2 4/5] emulator/bthost: Add initial rfcomm handling
From: Marcin Kraglak @ 2014-01-07 10:59 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1389092354-32544-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..8638f13 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->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

* [PATCHv2 3/5] monitor: Add rfcomm.h to tree
From: Marcin Kraglak @ 2014-01-07 10:59 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1389092354-32544-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..02a1256
--- /dev/null
+++ b/monitor/rfcomm.h
@@ -0,0 +1,47 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2013 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

* [PATCHv2 2/5] tools/rfcomm-tester: Add basic rfcomm test case
From: Marcin Kraglak @ 2014-01-07 10:59 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1389092354-32544-1-git-send-email-marcin.kraglak@tieto.com>

This test case verifies creating rfcomm socket.
---
 Makefile.tools        |   9 +-
 tools/rfcomm-tester.c | 257 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 264 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 194e2e6..af87f75 100644
--- a/tools/rfcomm-tester.c
+++ b/tools/rfcomm-tester.c
@@ -25,12 +25,269 @@
 #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:
+	case BT_HCI_CMD_LE_SET_ADV_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);
+	if (data->hciemu_type == HCIEMU_TYPE_LE)
+		bthost_set_adv_enable(bthost, 0x01);
+	else
+		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");
+
+	if (data->hciemu_type == HCIEMU_TYPE_BREDR)
+		mgmt_send(data->mgmt, MGMT_OP_SET_SSP, data->mgmt_index,
+				sizeof(param), param, NULL, NULL, NULL);
+	else
+		mgmt_send(data->mgmt, MGMT_OP_SET_LE, 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_bredr(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_bredr("Basic RFCOMM Socket - Success", NULL,
+					setup_powered_client, test_basic);
+
 	return tester_run();
 }
-- 
1.8.3.1


^ permalink raw reply related

* [PATCHv2 1/5] tools/rfcomm-tester: Initial version of rfcomm-tester
From: Marcin Kraglak @ 2014-01-07 10:59 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..194e2e6
--- /dev/null
+++ b/tools/rfcomm-tester.c
@@ -0,0 +1,36 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2013  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

* [PATCH 2/2] android: Send remote devices properties on enable
From: Lukasz Rymanowski @ 2014-01-07 10:53 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: szymon.janc, Lukasz Rymanowski
In-Reply-To: <1389092005-10302-1-git-send-email-lukasz.rymanowski@tieto.com>

If there is any bonded device stored then on bluetooth enable we
should send notification with its properties.

Change-Id: Ia14ae7379dd986d67e81161b86f3c02475540d7b
---
 android/bluetooth.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/android/bluetooth.c b/android/bluetooth.c
index e0673bb..9da988b 100644
--- a/android/bluetooth.c
+++ b/android/bluetooth.c
@@ -2636,6 +2636,18 @@ static void get_remote_device_props(struct device *dev)
 	get_device_timestamp(dev);
 }
 
+static void send_bonded_devices_props(void)
+{
+	GSList *l;
+
+	for (l = devices; l; l = g_slist_next(l)) {
+		struct device *dev = l->data;
+
+		if (dev->bond_state == HAL_BOND_STATE_BONDED)
+			get_remote_device_props(dev);
+	}
+}
+
 static void handle_enable_cmd(const void *buf, uint16_t len)
 {
 	uint8_t status;
@@ -2644,6 +2656,9 @@ static void handle_enable_cmd(const void *buf, uint16_t len)
 	 * enabling adapter */
 	get_adapter_properties();
 
+	/* Sent also properties of bonded devices */
+	send_bonded_devices_props();
+
 	if (adapter.current_settings & MGMT_SETTING_POWERED) {
 		status = HAL_STATUS_DONE;
 		goto failed;
-- 
1.8.4


^ permalink raw reply related

* [PATCH 1/2] android: Add wrapper function for get remote dev properties
From: Lukasz Rymanowski @ 2014-01-07 10:53 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: szymon.janc, Lukasz Rymanowski

Change-Id: Iab584580562534e2489dc6c8213f6066bbd8bd46
---
 android/bluetooth.c | 123 +++++++++++++++++++++++++++-------------------------
 1 file changed, 64 insertions(+), 59 deletions(-)

diff --git a/android/bluetooth.c b/android/bluetooth.c
index 3cbf68d..e0673bb 100644
--- a/android/bluetooth.c
+++ b/android/bluetooth.c
@@ -2550,56 +2550,6 @@ static void handle_get_remote_services_cmd(const void *buf, uint16_t len)
 									status);
 }
 
-static void handle_enable_cmd(const void *buf, uint16_t len)
-{
-	uint8_t status;
-
-	/* Framework expects all properties to be emitted while
-	 * enabling adapter */
-	get_adapter_properties();
-
-	if (adapter.current_settings & MGMT_SETTING_POWERED) {
-		status = HAL_STATUS_DONE;
-		goto failed;
-	}
-
-	if (!set_mode(MGMT_OP_SET_POWERED, 0x01)) {
-		status = HAL_STATUS_FAILED;
-		goto failed;
-	}
-
-	status = HAL_STATUS_SUCCESS;
-failed:
-	ipc_send_rsp(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_ENABLE, status);
-}
-
-static void handle_disable_cmd(const void *buf, uint16_t len)
-{
-	uint8_t status;
-
-	if (!(adapter.current_settings & MGMT_SETTING_POWERED)) {
-		status = HAL_STATUS_DONE;
-		goto failed;
-	}
-
-	if (!set_mode(MGMT_OP_SET_POWERED, 0x00)) {
-		status = HAL_STATUS_FAILED;
-		goto failed;
-	}
-
-	status = HAL_STATUS_SUCCESS;
-failed:
-	ipc_send_rsp(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_DISABLE, status);
-}
-
-static void handle_get_adapter_props_cmd(const void *buf, uint16_t len)
-{
-	get_adapter_properties();
-
-	ipc_send_rsp(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_GET_ADAPTER_PROPS,
-							HAL_STATUS_SUCCESS);
-}
-
 static uint8_t get_device_uuids(struct device *dev)
 {
 	send_device_uuids_notif(dev);
@@ -2673,6 +2623,69 @@ 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_enable_cmd(const void *buf, uint16_t len)
+{
+	uint8_t status;
+
+	/* Framework expects all properties to be emitted while
+	 * enabling adapter */
+	get_adapter_properties();
+
+	if (adapter.current_settings & MGMT_SETTING_POWERED) {
+		status = HAL_STATUS_DONE;
+		goto failed;
+	}
+
+	if (!set_mode(MGMT_OP_SET_POWERED, 0x01)) {
+		status = HAL_STATUS_FAILED;
+		goto failed;
+	}
+
+	status = HAL_STATUS_SUCCESS;
+failed:
+	ipc_send_rsp(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_ENABLE, status);
+}
+
+static void handle_disable_cmd(const void *buf, uint16_t len)
+{
+	uint8_t status;
+
+	if (!(adapter.current_settings & MGMT_SETTING_POWERED)) {
+		status = HAL_STATUS_DONE;
+		goto failed;
+	}
+
+	if (!set_mode(MGMT_OP_SET_POWERED, 0x00)) {
+		status = HAL_STATUS_FAILED;
+		goto failed;
+	}
+
+	status = HAL_STATUS_SUCCESS;
+failed:
+	ipc_send_rsp(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_DISABLE, status);
+}
+
+static void handle_get_adapter_props_cmd(const void *buf, uint16_t len)
+{
+	get_adapter_properties();
+
+	ipc_send_rsp(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_GET_ADAPTER_PROPS,
+							HAL_STATUS_SUCCESS);
+}
+
 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;
 
-- 
1.8.4


^ permalink raw reply related

* Re: [PATCH 1/4] android/pan: Register Network Access Point
From: Ravi kumar Veeramally @ 2014-01-07 10:48 UTC (permalink / raw)
  To: linux-bluetooth, johan.hedberg
In-Reply-To: <20140107101842.GA20861@x220.p-661hnu-f1>

Hi Johan,

On 01/07/2014 12:18 PM, Johan Hedberg wrote:
> Hi Ravi,
>
> On Tue, Jan 07, 2014, Ravi kumar Veeramally wrote:
>>>> @@ -49,7 +54,7 @@
>>>>   static bdaddr_t adapter_addr;
>>>>   GSList *devices = NULL;
>>>>   uint8_t local_role = HAL_PAN_ROLE_NONE;
>>>> -static uint32_t record_id = 0;
>>>> +char bridge[5] = "bnep\0";
>>> This last line raises several questions. Firstly, C-strings have an
>>> implicit nul-character at the end so no need to explicitly try to add
>>> one there. You also don't need to have an explicit size between the
>>> square brackets since this is automatically calculated if you do
>>> initialization upon declaration. Why isn't this static? Why isn't it
>>> const? Would a simple define make more sense instead of a dedicated
>>> variable?
>>   I tried these but there are some warnings.
>>
>> #define BNEP_BRIDGE   "bnep"
>> static char bridge[] = "bnep";
>> static char *bridge = "bnep";
>>
>> ==10198== Warning: noted but unhandled ioctl 0x89a1 with no
>> size/direction hints
>> ==10198==    This could cause spurious value errors to appear.
>> ==10198==    See README_MISSING_SYSCALL_OR_IOCTL for guidance on
>> writing a proper wrapper.
> Is this from valgrind?
    Yes.
> If so, then I think it's fine to ignore it as it
> simply doesn't know the details of all ioctls. We get this kind of
> stuff for Bluetooth specific ioctls too. I.e. go with whatever is the
> simplest (probably the define).
  Ok, I will change to define and send you v2.

Regards,
Ravi.

^ permalink raw reply

* Re: [PATCH 1/4] android/pan: Register Network Access Point
From: Johan Hedberg @ 2014-01-07 10:18 UTC (permalink / raw)
  To: Ravi kumar Veeramally; +Cc: linux-bluetooth
In-Reply-To: <52CBCF93.7060604@linux.intel.com>

Hi Ravi,

On Tue, Jan 07, 2014, Ravi kumar Veeramally wrote:
> >>@@ -49,7 +54,7 @@
> >>  static bdaddr_t adapter_addr;
> >>  GSList *devices = NULL;
> >>  uint8_t local_role = HAL_PAN_ROLE_NONE;
> >>-static uint32_t record_id = 0;
> >>+char bridge[5] = "bnep\0";
> >This last line raises several questions. Firstly, C-strings have an
> >implicit nul-character at the end so no need to explicitly try to add
> >one there. You also don't need to have an explicit size between the
> >square brackets since this is automatically calculated if you do
> >initialization upon declaration. Why isn't this static? Why isn't it
> >const? Would a simple define make more sense instead of a dedicated
> >variable?
> 
>  I tried these but there are some warnings.
> 
> #define BNEP_BRIDGE   "bnep"
> static char bridge[] = "bnep";
> static char *bridge = "bnep";
> 
> ==10198== Warning: noted but unhandled ioctl 0x89a1 with no
> size/direction hints
> ==10198==    This could cause spurious value errors to appear.
> ==10198==    See README_MISSING_SYSCALL_OR_IOCTL for guidance on
> writing a proper wrapper.

Is this from valgrind? If so, then I think it's fine to ignore it as it
simply doesn't know the details of all ioctls. We get this kind of
stuff for Bluetooth specific ioctls too. I.e. go with whatever is the
simplest (probably the define).

Johan

^ permalink raw reply

* Re: [PATCH 1/4] android/pan: Register Network Access Point
From: Ravi kumar Veeramally @ 2014-01-07  9:57 UTC (permalink / raw)
  To: linux-bluetooth, johan.hedberg
In-Reply-To: <20140107085930.GB9155@x220.p-661hnu-f1>

Hi Johan,

On 01/07/2014 10:59 AM, Johan Hedberg wrote:
> Hi Ravi,
>
> On Mon, Jan 06, 2014, Ravi kumar Veeramally wrote:
>> 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 | 116 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
>>   1 file changed, 112 insertions(+), 4 deletions(-)
>>
>> diff --git a/android/pan.c b/android/pan.c
>> index 38e353d..93f712f 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"
>> @@ -49,7 +54,7 @@
>>   static bdaddr_t adapter_addr;
>>   GSList *devices = NULL;
>>   uint8_t local_role = HAL_PAN_ROLE_NONE;
>> -static uint32_t record_id = 0;
>> +char bridge[5] = "bnep\0";
> This last line raises several questions. Firstly, C-strings have an
> implicit nul-character at the end so no need to explicitly try to add
> one there. You also don't need to have an explicit size between the
> square brackets since this is automatically calculated if you do
> initialization upon declaration. Why isn't this static? Why isn't it
> const? Would a simple define make more sense instead of a dedicated
> variable?

  I tried these but there are some warnings.

#define BNEP_BRIDGE   "bnep"
static char bridge[] = "bnep";
static char *bridge = "bnep";

==10198== Warning: noted but unhandled ioctl 0x89a1 with no 
size/direction hints
==10198==    This could cause spurious value errors to appear.
==10198==    See README_MISSING_SYSCALL_OR_IOCTL for guidance on writing 
a proper wrapper.

char bridge[5] = "bnep\0"; worked fine (yes, like you said static can be used).

Regards,
Ravi.


^ permalink raw reply

* Re: [PATCH 1/4] android/pan: Register Network Access Point
From: Johan Hedberg @ 2014-01-07  8:59 UTC (permalink / raw)
  To: Ravi kumar Veeramally; +Cc: linux-bluetooth
In-Reply-To: <1389043592-5616-2-git-send-email-ravikumar.veeramally@linux.intel.com>

Hi Ravi,

On Mon, Jan 06, 2014, Ravi kumar Veeramally wrote:
> 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 | 116 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
>  1 file changed, 112 insertions(+), 4 deletions(-)
> 
> diff --git a/android/pan.c b/android/pan.c
> index 38e353d..93f712f 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"
> @@ -49,7 +54,7 @@
>  static bdaddr_t adapter_addr;
>  GSList *devices = NULL;
>  uint8_t local_role = HAL_PAN_ROLE_NONE;
> -static uint32_t record_id = 0;
> +char bridge[5] = "bnep\0";

This last line raises several questions. Firstly, C-strings have an
implicit nul-character at the end so no need to explicitly try to add
one there. You also don't need to have an explicit size between the
square brackets since this is automatically calculated if you do
initialization upon declaration. Why isn't this static? Why isn't it
const? Would a simple define make more sense instead of a dedicated
variable?

Johan

^ permalink raw reply

* Re: [PATCH] btmon: Fix compiler warnings
From: Johan Hedberg @ 2014-01-07  8:43 UTC (permalink / raw)
  To: Andrei Emeltchenko; +Cc: linux-bluetooth
In-Reply-To: <1389081946-28347-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

Hi Andrei,

On Tue, Jan 07, 2014, Andrei Emeltchenko wrote:
> When building for Android this fixes following warnings:
> ...
> monitor/ellisys.c: In function 'ellisys_inject_hci':
> monitor/ellisys.c:159:2: warning: implicit declaration of function 'writev'
> [-Wimplicit-function-declaration]
> ...
> ---
>  monitor/ellisys.c | 1 +
>  1 file changed, 1 insertion(+)

Applied. Thanks.

Johan

^ permalink raw reply

* [PATCH] btmon: Fix compiler warnings
From: Andrei Emeltchenko @ 2014-01-07  8:05 UTC (permalink / raw)
  To: linux-bluetooth

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

When building for Android this fixes following warnings:
...
monitor/ellisys.c: In function 'ellisys_inject_hci':
monitor/ellisys.c:159:2: warning: implicit declaration of function 'writev'
[-Wimplicit-function-declaration]
...
---
 monitor/ellisys.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/monitor/ellisys.c b/monitor/ellisys.c
index d21c164..dae690f 100644
--- a/monitor/ellisys.c
+++ b/monitor/ellisys.c
@@ -32,6 +32,7 @@
 #include <time.h>
 #include <sys/time.h>
 #include <sys/socket.h>
+#include <sys/uio.h>
 
 #include <netdb.h>
 #include <arpa/inet.h>
-- 
1.8.3.2


^ permalink raw reply related

* Re: [PATCH v3 0/4] Regression fixes for rfcomm/tty.c
From: Marcel Holtmann @ 2014-01-06 21:57 UTC (permalink / raw)
  To: Gianluca Anzolin
  Cc: Gustavo F. Padovan, peter,
	linux-bluetooth@vger.kernel.org development, Greg KH, jslaby,
	stable
In-Reply-To: <1389039834-24491-1-git-send-email-gianluca@sottospazio.it>

Hi Gianluca,

> The following patches fix three regressions introduced with the
> rfcomm tty_port conversion.
> 
> The first patch restores the expected behaviour of the rfcomm port when
> it's created with the flag RFCOMM_RELEASE_ONHUP.
> 
> The second patch moves rfcomm_get_device() and is preparatory for the
> third patch.
> 
> The third patch fixes two regressions:
> 1) when the tty is opened with O_NONBLOCK or CLOCAL is set (fixes
>   wvdial)
> 2) when the rfcomm device is created with the flag RFCOMM_REUSE_DLC
>   (fixes ModemManager)
> 
> The fourth patch removes rfcomm_dev_carrier_raised().
> 
> Changes from v2:
>  * Fix the style of if statements in rfcomm_dev_activate().
> 
> Changes from v1:
>  * Removed the device_move() fix which is now incorporated in a new patch.
> 
> Gianluca Anzolin (4):
>  rfcomm: release the port when the last user closes the tty
>  rfcomm: move rfcomm_get_device() before rfcomm_dev_activate()
>  rfcomm: always wait for a bt connection on open()
>  rfcomm: remove rfcomm_carrier_raised()
> 
> net/bluetooth/rfcomm/tty.c | 103 +++++++++++++++++++++++++++++----------------
> 1 file changed, 66 insertions(+), 37 deletions(-)

all 4 patches have been applied to bluetooth-next tree.

Regards

Marcel


^ permalink raw reply

* [PATCH 4/4] android/pan: Remove connected PAN devices on profile unregister call
From: Ravi kumar Veeramally @ 2014-01-06 21:26 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Ravi kumar Veeramally
In-Reply-To: <1389043592-5616-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 499702f..b482d55 100644
--- a/android/pan.c
+++ b/android/pan.c
@@ -763,10 +763,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

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

---
 android/pan.c | 32 ++++++++++++++++++++++++++------
 1 file changed, 26 insertions(+), 6 deletions(-)

diff --git a/android/pan.c b/android/pan.c
index 87753a0..499702f 100644
--- a/android/pan.c
+++ b/android/pan.c
@@ -588,18 +588,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;
+	}
+
+	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 2/4] android/pan: Listen for incoming connections and accept in NAP role
From: Ravi kumar Veeramally @ 2014-01-06 21:26 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Ravi kumar Veeramally
In-Reply-To: <1389043592-5616-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 | 191 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 189 insertions(+), 2 deletions(-)

diff --git a/android/pan.c b/android/pan.c
index 93f712f..87753a0 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(bridge, dev->iface, &dev->dst);
+		g_source_remove(dev->watch);
+		dev->watch = 0;
+	}
+
 	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 +311,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 +321,153 @@ 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, 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)
 {
 	FILE *f;
@@ -382,10 +542,22 @@ static void destroy_nap_device(void)
 	nap_remove_bridge();
 
 	nap_dev.record_id = 0;
+
+	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("");
@@ -394,6 +566,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 1/4] android/pan: Register Network Access Point
From: Ravi kumar Veeramally @ 2014-01-06 21:26 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Ravi kumar Veeramally
In-Reply-To: <1389043592-5616-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 | 116 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 112 insertions(+), 4 deletions(-)

diff --git a/android/pan.c b/android/pan.c
index 38e353d..93f712f 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"
@@ -49,7 +54,7 @@
 static bdaddr_t adapter_addr;
 GSList *devices = NULL;
 uint8_t local_role = HAL_PAN_ROLE_NONE;
-static uint32_t record_id = 0;
+char bridge[5] = "bnep\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,95 @@ failed:
 	ipc_send_rsp(HAL_SERVICE_ID_PAN, HAL_OP_PAN_DISCONNECT, status);
 }
 
+static int set_forward_delay(void)
+{
+	FILE *f;
+	char *path;
+
+	path = g_strdup_printf("/sys/class/net/%s/bridge/forward_delay",
+									bridge);
+	if (!path)
+		return -ENOMEM;
+
+	f = fopen(path, "r+");
+	g_free(path);
+	if (!f)
+		return -errno;
+
+	fprintf(f, "%d", 0);
+	fclose(f);
+
+	return 0;
+}
+
+static int nap_create_bridge(void)
+{
+	int sk, err;
+
+	DBG(" %s", bridge);
+
+	sk = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
+	if (sk < 0)
+		return -EOPNOTSUPP;
+
+	if (ioctl(sk, SIOCBRADDBR, bridge) == -1) {
+		err = -errno;
+		if (err != -EEXIST) {
+			close(sk);
+			return -EOPNOTSUPP;
+		}
+	}
+
+	err = set_forward_delay();
+	if (err < 0)
+		ioctl(sk, SIOCBRDELBR, bridge);
+
+	close(sk);
+
+	return err;
+}
+
+static int nap_remove_bridge(void)
+{
+	int sk, err;
+
+	DBG(" %s", bridge);
+
+	sk = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
+	if (sk < 0)
+		return -EOPNOTSUPP;
+
+	err = ioctl(sk, SIOCBRDELBR, 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 +541,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 +563,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();
 }
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH 0/4] Add support for NAP role
From: Ravi kumar Veeramally @ 2014-01-06 21:26 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Ravi kumar Veeramally

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 | 349 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 337 insertions(+), 12 deletions(-)

-- 
1.8.3.2


^ permalink raw reply

* [PATCH v3 4/4] rfcomm: remove rfcomm_carrier_raised()
From: Gianluca Anzolin @ 2014-01-06 20:23 UTC (permalink / raw)
  To: gustavo
  Cc: peter, marcel, linux-bluetooth, gregkh, jslaby, stable,
	Gianluca Anzolin
In-Reply-To: <1389039834-24491-1-git-send-email-gianluca@sottospazio.it>

Remove the rfcomm_carrier_raised() definition as that function isn't
used anymore.

Signed-off-by: Gianluca Anzolin <gianluca@sottospazio.it>
---
 net/bluetooth/rfcomm/tty.c | 8 --------
 1 file changed, 8 deletions(-)

diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c
index aeabade..f9c0980a 100644
--- a/net/bluetooth/rfcomm/tty.c
+++ b/net/bluetooth/rfcomm/tty.c
@@ -160,14 +160,6 @@ static int rfcomm_dev_activate(struct tty_port *port, struct tty_struct *tty)
 	return err;
 }
 
-/* we block the open until the dlc->state becomes BT_CONNECTED */
-static int rfcomm_dev_carrier_raised(struct tty_port *port)
-{
-	struct rfcomm_dev *dev = container_of(port, struct rfcomm_dev, port);
-
-	return (dev->dlc->state == BT_CONNECTED);
-}
-
 /* device-specific cleanup: close the dlc */
 static void rfcomm_dev_shutdown(struct tty_port *port)
 {
-- 
1.8.5.2

^ permalink raw reply related

* [PATCH v3 3/4] rfcomm: always wait for a bt connection on open()
From: Gianluca Anzolin @ 2014-01-06 20:23 UTC (permalink / raw)
  To: gustavo
  Cc: peter, marcel, linux-bluetooth, gregkh, jslaby, stable,
	Gianluca Anzolin
In-Reply-To: <1389039834-24491-1-git-send-email-gianluca@sottospazio.it>

This patch fixes two regressions introduced with the recent rfcomm tty
rework.

The current code uses the carrier_raised() method to wait for the
bluetooth connection when a process opens the tty.

However processes may open the port with the O_NONBLOCK flag or set the
CLOCAL termios flag: in these cases the open() syscall returns
immediately without waiting for the bluetooth connection to
complete.

This behaviour confuses userspace which expects an established bluetooth
connection.

The patch restores the old behaviour by waiting for the connection in
rfcomm_dev_activate() and removes carrier_raised() from the tty_port ops.

As a side effect the new code also fixes the case in which the rfcomm
tty device is created with the flag RFCOMM_REUSE_DLC: the old code
didn't call device_move() and ModemManager skipped the detection
probe. Now device_move() is always called inside rfcomm_dev_activate().

Signed-off-by: Gianluca Anzolin <gianluca@sottospazio.it>
Reported-by: Andrey Vihrov <andrey.vihrov@gmail.com>
Reported-by: Beson Chow <blc+bluez@mail.vanade.com>
---
 net/bluetooth/rfcomm/tty.c | 46 ++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 38 insertions(+), 8 deletions(-)

diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c
index 32ef9f9..aeabade 100644
--- a/net/bluetooth/rfcomm/tty.c
+++ b/net/bluetooth/rfcomm/tty.c
@@ -58,6 +58,7 @@ struct rfcomm_dev {
 	uint			modem_status;
 
 	struct rfcomm_dlc	*dlc;
+	wait_queue_head_t       conn_wait;
 
 	struct device		*tty_dev;
 
@@ -123,8 +124,40 @@ static struct device *rfcomm_get_device(struct rfcomm_dev *dev)
 static int rfcomm_dev_activate(struct tty_port *port, struct tty_struct *tty)
 {
 	struct rfcomm_dev *dev = container_of(port, struct rfcomm_dev, port);
+	DEFINE_WAIT(wait);
+	int err;
+
+	err = rfcomm_dlc_open(dev->dlc, &dev->src, &dev->dst, dev->channel);
+	if (err)
+		return err;
+
+	while (1) {
+		prepare_to_wait(&dev->conn_wait, &wait, TASK_INTERRUPTIBLE);
 
-	return rfcomm_dlc_open(dev->dlc, &dev->src, &dev->dst, dev->channel);
+		if (dev->dlc->state == BT_CLOSED) {
+			err = -dev->err;
+			break;
+		}
+
+		if (dev->dlc->state == BT_CONNECTED)
+			break;
+
+		if (signal_pending(current)) {
+			err = -ERESTARTSYS;
+			break;
+		}
+
+		tty_unlock(tty);
+		schedule();
+		tty_lock(tty);
+	}
+	finish_wait(&dev->conn_wait, &wait);
+
+	if (!err)
+		device_move(dev->tty_dev, rfcomm_get_device(dev),
+			    DPM_ORDER_DEV_AFTER_PARENT);
+
+	return err;
 }
 
 /* we block the open until the dlc->state becomes BT_CONNECTED */
@@ -151,7 +184,6 @@ static const struct tty_port_operations rfcomm_port_ops = {
 	.destruct = rfcomm_dev_destruct,
 	.activate = rfcomm_dev_activate,
 	.shutdown = rfcomm_dev_shutdown,
-	.carrier_raised = rfcomm_dev_carrier_raised,
 };
 
 static struct rfcomm_dev *__rfcomm_dev_get(int id)
@@ -258,6 +290,7 @@ static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc)
 
 	tty_port_init(&dev->port);
 	dev->port.ops = &rfcomm_port_ops;
+	init_waitqueue_head(&dev->conn_wait);
 
 	skb_queue_head_init(&dev->pending);
 
@@ -576,12 +609,9 @@ static void rfcomm_dev_state_change(struct rfcomm_dlc *dlc, int err)
 	BT_DBG("dlc %p dev %p err %d", dlc, dev, err);
 
 	dev->err = err;
-	if (dlc->state == BT_CONNECTED) {
-		device_move(dev->tty_dev, rfcomm_get_device(dev),
-			    DPM_ORDER_DEV_AFTER_PARENT);
+	wake_up_interruptible(&dev->conn_wait);
 
-		wake_up_interruptible(&dev->port.open_wait);
-	} else if (dlc->state == BT_CLOSED)
+	if (dlc->state == BT_CLOSED)
 		tty_port_tty_hangup(&dev->port, false);
 }
 
@@ -1103,7 +1133,7 @@ int __init rfcomm_init_ttys(void)
 	rfcomm_tty_driver->subtype	= SERIAL_TYPE_NORMAL;
 	rfcomm_tty_driver->flags	= TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
 	rfcomm_tty_driver->init_termios	= tty_std_termios;
-	rfcomm_tty_driver->init_termios.c_cflag	= B9600 | CS8 | CREAD | HUPCL;
+	rfcomm_tty_driver->init_termios.c_cflag	= B9600 | CS8 | CREAD | HUPCL | CLOCAL;
 	rfcomm_tty_driver->init_termios.c_lflag &= ~ICANON;
 	tty_set_operations(rfcomm_tty_driver, &rfcomm_ops);
 
-- 
1.8.5.2

^ permalink raw reply related

* [PATCH v3 2/4] rfcomm: move rfcomm_get_device() before rfcomm_dev_activate()
From: Gianluca Anzolin @ 2014-01-06 20:23 UTC (permalink / raw)
  To: gustavo
  Cc: peter, marcel, linux-bluetooth, gregkh, jslaby, stable,
	Gianluca Anzolin
In-Reply-To: <1389039834-24491-1-git-send-email-gianluca@sottospazio.it>

This is a preparatory patch which moves the rfcomm_get_device()
definition before rfcomm_dev_activate() where it will be used.

Signed-off-by: Gianluca Anzolin <gianluca@sottospazio.it>
---
 net/bluetooth/rfcomm/tty.c | 32 ++++++++++++++++----------------
 1 file changed, 16 insertions(+), 16 deletions(-)

diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c
index a535ef1..32ef9f9 100644
--- a/net/bluetooth/rfcomm/tty.c
+++ b/net/bluetooth/rfcomm/tty.c
@@ -103,6 +103,22 @@ static void rfcomm_dev_destruct(struct tty_port *port)
 	module_put(THIS_MODULE);
 }
 
+static struct device *rfcomm_get_device(struct rfcomm_dev *dev)
+{
+	struct hci_dev *hdev;
+	struct hci_conn *conn;
+
+	hdev = hci_get_route(&dev->dst, &dev->src);
+	if (!hdev)
+		return NULL;
+
+	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &dev->dst);
+
+	hci_dev_put(hdev);
+
+	return conn ? &conn->dev : NULL;
+}
+
 /* device-specific initialization: open the dlc */
 static int rfcomm_dev_activate(struct tty_port *port, struct tty_struct *tty)
 {
@@ -169,22 +185,6 @@ static struct rfcomm_dev *rfcomm_dev_get(int id)
 	return dev;
 }
 
-static struct device *rfcomm_get_device(struct rfcomm_dev *dev)
-{
-	struct hci_dev *hdev;
-	struct hci_conn *conn;
-
-	hdev = hci_get_route(&dev->dst, &dev->src);
-	if (!hdev)
-		return NULL;
-
-	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &dev->dst);
-
-	hci_dev_put(hdev);
-
-	return conn ? &conn->dev : NULL;
-}
-
 static ssize_t show_address(struct device *tty_dev, struct device_attribute *attr, char *buf)
 {
 	struct rfcomm_dev *dev = dev_get_drvdata(tty_dev);
-- 
1.8.5.2

^ permalink raw reply related

* [PATCH v3 1/4] rfcomm: release the port when the last user closes the tty
From: Gianluca Anzolin @ 2014-01-06 20:23 UTC (permalink / raw)
  To: gustavo
  Cc: peter, marcel, linux-bluetooth, gregkh, jslaby, stable,
	Gianluca Anzolin
In-Reply-To: <1389039834-24491-1-git-send-email-gianluca@sottospazio.it>

This patch fixes a userspace regression introduced by the commit
29cd718b.

If the rfcomm device was created with the flag RFCOMM_RELEASE_ONHUP the
user space expects that the tty_port is released as soon as the last
process closes the tty.

The current code attempts to release the port in the function
rfcomm_dev_state_change(). However it won't get a reference to the
relevant tty to send a HUP: at that point the tty is already destroyed
and therefore NULL.

This patch fixes the regression by taking over the tty refcount in the
tty install method(). This way the tty_port is automatically released as
soon as the tty is destroyed.

As a consequence the check for RFCOMM_RELEASE_ONHUP flag in the hangup()
method is now redundant. Instead we have to be careful with the reference
counting in the rfcomm_release_dev() function.

Signed-off-by: Gianluca Anzolin <gianluca@sottospazio.it>
Reported-by: Alexander Holler <holler@ahsoftware.de>
---
 net/bluetooth/rfcomm/tty.c | 21 ++++++++++++++-------
 1 file changed, 14 insertions(+), 7 deletions(-)

diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c
index 84fcf9f..a535ef1 100644
--- a/net/bluetooth/rfcomm/tty.c
+++ b/net/bluetooth/rfcomm/tty.c
@@ -437,7 +437,8 @@ static int rfcomm_release_dev(void __user *arg)
 		tty_kref_put(tty);
 	}
 
-	if (!test_and_set_bit(RFCOMM_TTY_RELEASED, &dev->flags))
+	if (!test_bit(RFCOMM_RELEASE_ONHUP, &dev->flags) &&
+	    !test_and_set_bit(RFCOMM_TTY_RELEASED, &dev->flags))
 		tty_port_put(&dev->port);
 
 	tty_port_put(&dev->port);
@@ -670,10 +671,20 @@ static int rfcomm_tty_install(struct tty_driver *driver, struct tty_struct *tty)
 
 	/* install the tty_port */
 	err = tty_port_install(&dev->port, driver, tty);
-	if (err)
+	if (err) {
 		rfcomm_tty_cleanup(tty);
+		return err;
+	}
 
-	return err;
+	/* take over the tty_port reference if the port was created with the
+	 * flag RFCOMM_RELEASE_ONHUP. This will force the release of the port
+	 * when the last process closes the tty. The behaviour is expected by
+	 * userspace.
+	 */
+	if (test_bit(RFCOMM_RELEASE_ONHUP, &dev->flags))
+		tty_port_put(&dev->port);
+
+	return 0;
 }
 
 static int rfcomm_tty_open(struct tty_struct *tty, struct file *filp)
@@ -1010,10 +1021,6 @@ static void rfcomm_tty_hangup(struct tty_struct *tty)
 	BT_DBG("tty %p dev %p", tty, dev);
 
 	tty_port_hangup(&dev->port);
-
-	if (test_bit(RFCOMM_RELEASE_ONHUP, &dev->flags) &&
-	    !test_and_set_bit(RFCOMM_TTY_RELEASED, &dev->flags))
-		tty_port_put(&dev->port);
 }
 
 static int rfcomm_tty_tiocmget(struct tty_struct *tty)
-- 
1.8.5.2

^ permalink raw reply related

* [PATCH v3 0/4] Regression fixes for rfcomm/tty.c
From: Gianluca Anzolin @ 2014-01-06 20:23 UTC (permalink / raw)
  To: gustavo
  Cc: peter, marcel, linux-bluetooth, gregkh, jslaby, stable,
	Gianluca Anzolin

The following patches fix three regressions introduced with the
rfcomm tty_port conversion.

The first patch restores the expected behaviour of the rfcomm port when
it's created with the flag RFCOMM_RELEASE_ONHUP.

The second patch moves rfcomm_get_device() and is preparatory for the
third patch.

The third patch fixes two regressions:
1) when the tty is opened with O_NONBLOCK or CLOCAL is set (fixes
   wvdial)
2) when the rfcomm device is created with the flag RFCOMM_REUSE_DLC
   (fixes ModemManager)

The fourth patch removes rfcomm_dev_carrier_raised().

Changes from v2:
  * Fix the style of if statements in rfcomm_dev_activate().

Changes from v1:
  * Removed the device_move() fix which is now incorporated in a new patch.

Gianluca Anzolin (4):
  rfcomm: release the port when the last user closes the tty
  rfcomm: move rfcomm_get_device() before rfcomm_dev_activate()
  rfcomm: always wait for a bt connection on open()
  rfcomm: remove rfcomm_carrier_raised()

 net/bluetooth/rfcomm/tty.c | 103 +++++++++++++++++++++++++++++----------------
 1 file changed, 66 insertions(+), 37 deletions(-)

-- 
1.8.5.2

^ permalink raw reply

* Re: [PATCH v2 3/4] rfcomm: always wait for a bt connection on open()
From: Gianluca Anzolin @ 2014-01-06 19:37 UTC (permalink / raw)
  To: Marcel Holtmann
  Cc: Gustavo F. Padovan, peter,
	linux-bluetooth@vger.kernel.org development, Greg KH, jslaby,
	stable
In-Reply-To: <4321EF0E-97F4-4236-B763-0D0213BE97A8@holtmann.org>

On Mon, Jan 06, 2014 at 11:17:06AM -0800, Marcel Holtmann wrote:
> don’t do an if-else-else if statement here. Just break.
> 
> 	if (dev->dlc->state == BT_CLOSED) {
> 		..
> 		break;	
> 	}
> 
> 	if (dev->dlc->state == BT_CONNECTED)
> 		break;
> 
> 	if (signal_pending(..)) {
> 		..
> 		break;
> 	}

I'll change the code.

> > -	rfcomm_tty_driver->init_termios.c_cflag	= B9600 | CS8 | CREAD | HUPCL;
> > +	rfcomm_tty_driver->init_termios.c_cflag	= B9600 | CS8 | CREAD | HUPCL | CLOCAL;
> 
> Is adding CLOCAL by default intentional?

Yes, I removed it before because I relied on the carrier_raised() tty_port
method. But it turned out it wasn't a good idea because some code (wvdial
for example) set that flag on exit, leaving a non-working tty for subsequent
open() calls.

Now I restored the original flags, even if CLOCAL is actually ignored by the
code.

I will shortly send a third iteration with the fixed if statements.

Thanks,
Gianluca

> > 	rfcomm_tty_driver->init_termios.c_lflag &= ~ICANON;
> > 	tty_set_operations(rfcomm_tty_driver, &rfcomm_ops);
> 
> Regards
> 
> Marcel
> 

^ permalink raw reply

* Re: [PATCH] unit: Fix test failures with glib 2.39.0
From: Johan Hedberg @ 2014-01-06 19:28 UTC (permalink / raw)
  To: Colin Watson; +Cc: linux-bluetooth
In-Reply-To: <20140106120700.GZ5883@riva.ucam.org>

Hi Colin,

On Mon, Jan 06, 2014, Colin Watson wrote:
> glib 2.39.0 made this change:
> 
>    - g_source_remove() will now throw a critical in the case that you
>      try to remove a non-existent source.  We expect that there is some
>      code in the wild that will fall afoul of this new critical but
>      considering that we now reuse source IDs, this code is already
>      broken and should probably be fixed.
> 
> This patch fixes the test suite to keep better track of whether sources have
> already been removed and avoid double-removals.
> ---
>  unit/test-avdtp.c          |  8 ++++++--
>  unit/test-gobex-transfer.c |  6 ++++--
>  unit/test-gobex.c          | 13 ++++++++-----
>  unit/util.c                |  1 +
>  unit/util.h                |  1 +
>  5 files changed, 20 insertions(+), 9 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