* Re: [PATCHv2 1/2] android/tester: Add Socket test close and listen
From: Johan Hedberg @ 2013-12-19 9:09 UTC (permalink / raw)
To: Andrei Emeltchenko; +Cc: linux-bluetooth
In-Reply-To: <1387443100-4768-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
Hi Andrei,
On Thu, Dec 19, 2013, Andrei Emeltchenko wrote:
> This test the situation when Android close file descriptor we passed to
> it and try to listen() again.
> ---
> android/android-tester.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 60 insertions(+)
Both patches have been applied. Thanks.
Johan
^ permalink raw reply
* Re: [PATCHv2 1/3] android/socket: Refactor connect to allow directly connect to rfcomm
From: Johan Hedberg @ 2013-12-19 9:08 UTC (permalink / raw)
To: Andrei Emeltchenko; +Cc: linux-bluetooth
In-Reply-To: <1387442960-4584-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
Hi Andrei,
On Thu, Dec 19, 2013, Andrei Emeltchenko wrote:
> Since Socket HAL allows us to specify RFCOMM channel number and directly
> connect refactor send function to allow connect directly is uuid is zero
> and channel number is specified.
> ---
> android/socket.c | 71 +++++++++++++++++++++++++++++++-------------------------
> 1 file changed, 39 insertions(+), 32 deletions(-)
All three patches have been applied. Thanks.
Johan
^ permalink raw reply
* [PATCH] android/build: Adding l2test to Android.mk
From: Sebastian Chlad @ 2013-12-19 9:06 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Sebastian Chlad
Enabling l2test tool for the android target
---
android/Android.mk | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
diff --git a/android/Android.mk b/android/Android.mk
index ebc3219..c59df7a 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -226,3 +226,31 @@ LOCAL_MODULE_TAGS := optional
LOCAL_MODULE := audio.a2dp.default
include $(BUILD_SHARED_LIBRARY)
+
+#
+# l2cap-test
+#
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+ ../tools/l2test.c \
+ ../lib/bluetooth.c \
+ ../lib/hci.c \
+
+lib_headers := \
+ ../lib/bluetooth.h \
+ ../lib/l2cap.h \
+
+LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH)/.. \
+ $(LOCAL_PATH)/../lib \
+ $(LOCAL_PATH)/../src/shared \
+
+LOCAL_CFLAGS := $(BLUEZ_COMMON_CFLAGS)
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
+LOCAL_MODULE_TAGS := eng
+LOCAL_MODULE := l2test
+
+include $(BUILD_EXECUTABLE)
--
1.8.1.2
^ permalink raw reply related
* [PATCHv2 2/2] android/socket: Handle Android events for server socket
From: Andrei Emeltchenko @ 2013-12-19 8:51 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1387443100-4768-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Add watch for tracking events from Android framework for server socket.
Android might want to close server connection, in this case we close
our listening socket and cleaning up rfsock structure. Glib watch is
added with high priority to avoid races.
---
android/socket.c | 32 +++++++++++++++++++++++++++++++-
1 file changed, 31 insertions(+), 1 deletion(-)
diff --git a/android/socket.c b/android/socket.c
index 94a44fc..5a03a80 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -622,6 +622,24 @@ static bool sock_send_accept(struct rfcomm_sock *rfsock, bdaddr_t *bdaddr,
return true;
}
+static gboolean sock_server_stack_event_cb(GIOChannel *io, GIOCondition cond,
+ gpointer data)
+{
+ struct rfcomm_sock *rfsock = data;
+
+ DBG("sock %d cond %d", g_io_channel_unix_get_fd(io), cond);
+
+ if (cond & G_IO_NVAL)
+ return FALSE;
+
+ if (cond & (G_IO_ERR | G_IO_HUP )) {
+ servers = g_list_remove(servers, rfsock);
+ cleanup_rfsock(rfsock);
+ }
+
+ return FALSE;
+}
+
static void accept_cb(GIOChannel *io, GError *err, gpointer user_data)
{
struct rfcomm_sock *rfsock = user_data;
@@ -697,10 +715,12 @@ static void handle_listen(const void *buf, uint16_t len)
const struct profile_info *profile;
struct rfcomm_sock *rfsock = NULL;
BtIOSecLevel sec_level;
- GIOChannel *io;
+ GIOChannel *io, *io_stack;
+ GIOCondition cond;
GError *err = NULL;
int hal_fd = -1;
int chan;
+ guint id;
DBG("");
@@ -738,6 +758,16 @@ static void handle_listen(const void *buf, uint16_t len)
g_io_channel_set_close_on_unref(io, FALSE);
g_io_channel_unref(io);
+ /* Handle events from Android */
+ cond = G_IO_HUP | G_IO_ERR | G_IO_NVAL;
+ io_stack = g_io_channel_unix_new(rfsock->fd);
+ id = g_io_add_watch_full(io_stack, G_PRIORITY_HIGH, cond,
+ sock_server_stack_event_cb, rfsock,
+ NULL);
+ g_io_channel_unref(io_stack);
+
+ rfsock->stack_watch = id;
+
DBG("real_sock %d fd %d hal_fd %d", rfsock->real_sock, rfsock->fd,
hal_fd);
--
1.8.3.2
^ permalink raw reply related
* [PATCHv2 1/2] android/tester: Add Socket test close and listen
From: Andrei Emeltchenko @ 2013-12-19 8:51 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1387379717-1457-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
This test the situation when Android close file descriptor we passed to
it and try to listen() again.
---
android/android-tester.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 60 insertions(+)
diff --git a/android/android-tester.c b/android/android-tester.c
index 8a2861e..c24f5a6 100644
--- a/android/android-tester.c
+++ b/android/android-tester.c
@@ -1141,6 +1141,62 @@ clean:
close(sock_fd);
}
+static void test_listen_close(const void *test_data)
+{
+ struct test_data *data = tester_get_data();
+ const struct socket_data *test = data->test_data;
+ bt_status_t status;
+ int sock_fd = -1;
+
+ status = data->if_sock->listen(test->sock_type,
+ test->service_name, test->service_uuid,
+ test->channel, &sock_fd, test->flags);
+ if (status != test->expected_status) {
+ tester_warn("sock->listen() failed");
+ tester_test_failed();
+ goto clean;
+ }
+
+ /* Check that file descriptor is valid */
+ if (status == BT_STATUS_SUCCESS && fcntl(sock_fd, F_GETFD) < 0) {
+ tester_warn("sock_fd %d is not valid", sock_fd);
+ tester_test_failed();
+ return;
+ }
+
+ tester_print("Got valid sock_fd: %d", sock_fd);
+
+ /* Now close sock_fd */
+ close(sock_fd);
+ sock_fd = -1;
+
+ /* Try to listen again */
+ status = data->if_sock->listen(test->sock_type,
+ test->service_name, test->service_uuid,
+ test->channel, &sock_fd, test->flags);
+ if (status != test->expected_status) {
+ tester_warn("sock->listen() failed");
+ tester_test_failed();
+ goto clean;
+ }
+
+ /* Check that file descriptor is valid */
+ if (status == BT_STATUS_SUCCESS && fcntl(sock_fd, F_GETFD) < 0) {
+ tester_warn("sock_fd %d is not valid", sock_fd);
+ tester_test_failed();
+ return;
+ }
+
+ tester_print("Got valid sock_fd: %d", sock_fd);
+
+ tester_test_passed();
+
+clean:
+ if (sock_fd >= 0)
+ close(sock_fd);
+
+}
+
static void test_generic_connect(const void *test_data)
{
struct test_data *data = tester_get_data();
@@ -1363,6 +1419,10 @@ int main(int argc, char *argv[])
&btsock_success_check_chan,
setup_socket_interface, test_generic_listen, teardown);
+ test_bredrle("Socket Listen - Close and Listen again",
+ &btsock_success_check_chan,
+ setup_socket_interface, test_listen_close, teardown);
+
test_bredrle("Socket Connect - Invalid: sock_type 0",
&btsock_inv_param_socktype, setup_socket_interface,
test_generic_connect, teardown);
--
1.8.3.2
^ permalink raw reply related
* [PATCHv2 3/3] android/tester: Test that connect call returns channel number
From: Andrei Emeltchenko @ 2013-12-19 8:49 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1387442960-4584-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
The test connects to emulated bthost and read channel number
---
android/android-tester.c | 117 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 117 insertions(+)
diff --git a/android/android-tester.c b/android/android-tester.c
index 55fa702..8a2861e 100644
--- a/android/android-tester.c
+++ b/android/android-tester.c
@@ -1080,6 +1080,27 @@ static void setup_socket_interface(const void *test_data)
tester_setup_complete();
}
+static void setup_socket_interface_enabled(const void *test_data)
+{
+ struct test_data *data = tester_get_data();
+ const void *sock;
+ bt_status_t status;
+
+ setup(data);
+
+ sock = data->if_bluetooth->get_profile_interface(BT_PROFILE_SOCKETS_ID);
+ if (!sock) {
+ tester_setup_failed();
+ return;
+ }
+
+ data->if_sock = sock;
+
+ status = data->if_bluetooth->enable();
+ if (status != BT_STATUS_SUCCESS)
+ tester_setup_failed();
+}
+
static void test_generic_listen(const void *test_data)
{
struct test_data *data = tester_get_data();
@@ -1148,6 +1169,97 @@ clean:
close(sock_fd);
}
+static gboolean socket_chan_cb(GIOChannel *io, GIOCondition cond,
+ gpointer user_data)
+{
+ int sock_fd = g_io_channel_unix_get_fd(io);
+ struct test_data *data = tester_get_data();
+ const struct socket_data *test = data->test_data;
+ int channel, len;
+
+ tester_print("%s", __func__);
+
+ if (cond & G_IO_HUP) {
+ tester_warn("Socket %d hang up", sock_fd);
+ goto failed;
+ }
+
+ if (cond & (G_IO_ERR | G_IO_NVAL)) {
+ tester_warn("Socket error: sock %d cond %d", sock_fd, cond);
+ goto failed;
+ }
+
+ if (test->test_channel) {
+ len = read(sock_fd, &channel, sizeof(channel));
+ if (len != sizeof(channel) || channel != test->channel)
+ goto failed;
+
+ tester_print("read correct channel: %d", channel);
+ tester_test_passed();
+ return FALSE;
+ }
+
+failed:
+ tester_test_failed();
+ return FALSE;
+}
+
+static void test_socket_real_connect(const void *test_data)
+{
+ struct test_data *data = tester_get_data();
+ const struct socket_data *test = data->test_data;
+ struct bthost *bthost = hciemu_client_get_host(data->hciemu);
+ const uint8_t *client_bdaddr;
+ bt_bdaddr_t emu_bdaddr;
+ bt_status_t status;
+ int sock_fd = -1;
+
+ client_bdaddr = hciemu_get_client_bdaddr(data->hciemu);
+ if (!client_bdaddr) {
+ tester_warn("No client bdaddr");
+ tester_test_failed();
+ return;
+ }
+
+ bdaddr2android((bdaddr_t *) client_bdaddr, &emu_bdaddr);
+
+ bthost_set_server_psm(bthost, 0x0003);
+
+ status = data->if_sock->connect(&emu_bdaddr, test->sock_type,
+ test->service_uuid, test->channel,
+ &sock_fd, test->flags);
+ if (status != test->expected_status) {
+ tester_test_failed();
+ goto clean;
+ }
+
+ /* Check that file descriptor is valid */
+ if (status == BT_STATUS_SUCCESS && fcntl(sock_fd, F_GETFD) == -1) {
+ tester_test_failed();
+ return;
+ }
+
+ tester_print("status %d sock_fd %d", status, sock_fd);
+
+ if (status == BT_STATUS_SUCCESS) {
+ GIOChannel *io;
+
+ io = g_io_channel_unix_new(sock_fd);
+ g_io_channel_set_close_on_unref(io, TRUE);
+
+ g_io_add_watch(io, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
+ socket_chan_cb, NULL);
+
+ g_io_channel_unref(io);
+ }
+
+ return;
+
+clean:
+ if (sock_fd >= 0)
+ close(sock_fd);
+}
+
#define test_bredrle(name, data, test_setup, test, test_teardown) \
do { \
struct test_data *user; \
@@ -1267,5 +1379,10 @@ int main(int argc, char *argv[])
&btsock_inv_param_bdaddr,
setup_socket_interface, test_generic_connect, teardown);
+ test_bredrle("Socket Connect - Check returned chan",
+ &btsock_success_check_chan,
+ setup_socket_interface_enabled,
+ test_socket_real_connect, teardown);
+
return tester_run();
}
--
1.8.3.2
^ permalink raw reply related
* [PATCHv2 2/3] android/socket: Connect directly to RFCOMM channel if uuid is zero
From: Andrei Emeltchenko @ 2013-12-19 8:49 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1387442960-4584-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Check uuid and connect to specified RFCOMM channel directly if uuid is
zeroed.
---
android/socket.c | 24 ++++++++++++++++--------
1 file changed, 16 insertions(+), 8 deletions(-)
diff --git a/android/socket.c b/android/socket.c
index 656222e..94a44fc 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -929,6 +929,7 @@ static void handle_connect(const void *buf, uint16_t len)
{
const struct hal_cmd_sock_connect *cmd = buf;
struct rfcomm_sock *rfsock;
+ static uint8_t zero_uuid[16];
uuid_t uuid;
int hal_fd = -1;
@@ -940,17 +941,21 @@ static void handle_connect(const void *buf, uint16_t len)
android2bdaddr(cmd->bdaddr, &rfsock->dst);
- memset(&uuid, 0, sizeof(uuid));
- uuid.type = SDP_UUID128;
- memcpy(&uuid.value.uuid128, cmd->uuid, sizeof(uint128_t));
+ if (!memcmp(cmd->uuid, zero_uuid, sizeof(zero_uuid))) {
+ if (!do_connect(rfsock, cmd->channel))
+ goto failed;
+ } else {
+ memset(&uuid, 0, sizeof(uuid));
+ uuid.type = SDP_UUID128;
+ memcpy(&uuid.value.uuid128, cmd->uuid, sizeof(uint128_t));
- rfsock->profile = get_profile_by_uuid(cmd->uuid);
+ rfsock->profile = get_profile_by_uuid(cmd->uuid);
- if (bt_search_service(&adapter_addr, &rfsock->dst, &uuid,
+ if (bt_search_service(&adapter_addr, &rfsock->dst, &uuid,
sdp_search_cb, rfsock, NULL) < 0) {
- error("Failed to search SDP records");
- cleanup_rfsock(rfsock);
- goto failed;
+ error("Failed to search SDP records");
+ goto failed;
+ }
}
ipc_send_rsp_full(HAL_SERVICE_ID_SOCK, HAL_OP_SOCK_CONNECT, 0, NULL,
@@ -962,6 +967,9 @@ failed:
ipc_send_rsp(HAL_SERVICE_ID_SOCK, HAL_OP_SOCK_CONNECT,
HAL_STATUS_FAILED);
+ if (rfsock)
+ cleanup_rfsock(rfsock);
+
if (hal_fd >= 0)
close(hal_fd);
}
--
1.8.3.2
^ permalink raw reply related
* [PATCHv2 1/3] android/socket: Refactor connect to allow directly connect to rfcomm
From: Andrei Emeltchenko @ 2013-12-19 8:49 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1387376336-17092-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Since Socket HAL allows us to specify RFCOMM channel number and directly
connect refactor send function to allow connect directly is uuid is zero
and channel number is specified.
---
android/socket.c | 71 +++++++++++++++++++++++++++++++-------------------------
1 file changed, 39 insertions(+), 32 deletions(-)
diff --git a/android/socket.c b/android/socket.c
index cee4b6e..656222e 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -838,13 +838,47 @@ fail:
cleanup_rfsock(rfsock);
}
-static void sdp_search_cb(sdp_list_t *recs, int err, gpointer data)
+static bool do_connect(struct rfcomm_sock *rfsock, int chan)
{
- struct rfcomm_sock *rfsock = data;
BtIOSecLevel sec_level = BT_IO_SEC_MEDIUM;
+ GIOChannel *io;
GError *gerr = NULL;
+
+ if (rfsock->profile)
+ sec_level = rfsock->profile->sec_level;
+
+ io = bt_io_connect(connect_cb, rfsock, NULL, &gerr,
+ BT_IO_OPT_SOURCE_BDADDR, &adapter_addr,
+ BT_IO_OPT_DEST_BDADDR, &rfsock->dst,
+ BT_IO_OPT_CHANNEL, chan,
+ BT_IO_OPT_SEC_LEVEL, sec_level,
+ BT_IO_OPT_INVALID);
+ if (!io) {
+ error("Failed connect: %s", gerr->message);
+ g_error_free(gerr);
+ return false;
+ }
+
+ g_io_channel_set_close_on_unref(io, FALSE);
+ g_io_channel_unref(io);
+
+ if (write(rfsock->fd, &chan, sizeof(chan)) != sizeof(chan)) {
+ error("Error sending RFCOMM channel");
+ return false;
+ }
+
+ rfsock->real_sock = g_io_channel_unix_get_fd(io);
+ rfsock_set_buffer(rfsock);
+ rfsock->channel = chan;
+ connections = g_list_append(connections, rfsock);
+
+ return true;
+}
+
+static void sdp_search_cb(sdp_list_t *recs, int err, gpointer data)
+{
+ struct rfcomm_sock *rfsock = data;
sdp_list_t *list;
- GIOChannel *io;
int chan;
DBG("");
@@ -885,36 +919,9 @@ static void sdp_search_cb(sdp_list_t *recs, int err, gpointer data)
DBG("Got RFCOMM channel %d", chan);
- if (rfsock->profile)
- sec_level = rfsock->profile->sec_level;
-
- io = bt_io_connect(connect_cb, rfsock, NULL, &gerr,
- BT_IO_OPT_SOURCE_BDADDR, &adapter_addr,
- BT_IO_OPT_DEST_BDADDR, &rfsock->dst,
- BT_IO_OPT_CHANNEL, chan,
- BT_IO_OPT_SEC_LEVEL, sec_level,
- BT_IO_OPT_INVALID);
- if (!io) {
- error("Failed connect: %s", gerr->message);
- g_error_free(gerr);
- goto fail;
- }
-
- if (write(rfsock->fd, &chan, sizeof(chan)) != sizeof(chan)) {
- error("Error sending RFCOMM channel");
- goto fail;
- }
-
- rfsock->real_sock = g_io_channel_unix_get_fd(io);
- rfsock_set_buffer(rfsock);
- rfsock->channel = chan;
- connections = g_list_append(connections, rfsock);
-
- g_io_channel_unref(io);
-
- return;
+ if (do_connect(rfsock, chan))
+ return;
fail:
- connections = g_list_remove(connections, rfsock);
cleanup_rfsock(rfsock);
}
--
1.8.3.2
^ permalink raw reply related
* [PATCH_v5 5/5] bnep: Refactored bnep server apis for bridge addition and deletion
From: Ravi kumar Veeramally @ 2013-12-19 8:48 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Ravi kumar Veeramally
In-Reply-To: <1387442933-20681-1-git-send-email-ravikumar.veeramally@linux.intel.com>
To simplify bnep server realted bridge creation and deletion calls
provided extra apis and moved existing apis to static.
---
profiles/network/bnep.c | 50 +++++++++++++++++++++++++++++++++++++++++------
profiles/network/bnep.h | 9 +++------
profiles/network/server.c | 37 +++--------------------------------
3 files changed, 50 insertions(+), 46 deletions(-)
diff --git a/profiles/network/bnep.c b/profiles/network/bnep.c
index b7c3835..90728d3 100644
--- a/profiles/network/bnep.c
+++ b/profiles/network/bnep.c
@@ -151,7 +151,7 @@ int bnep_cleanup(void)
return 0;
}
-int bnep_conndel(const bdaddr_t *dst)
+static int bnep_conndel(const bdaddr_t *dst)
{
struct bnep_conndel_req req;
@@ -167,7 +167,7 @@ int bnep_conndel(const bdaddr_t *dst)
return 0;
}
-int bnep_connadd(int sk, uint16_t role, char *dev)
+static int bnep_connadd(int sk, uint16_t role, char *dev)
{
struct bnep_connadd_req req;
@@ -187,7 +187,7 @@ int bnep_connadd(int sk, uint16_t role, char *dev)
return 0;
}
-int bnep_if_up(const char *devname)
+static int bnep_if_up(const char *devname)
{
struct ifreq ifr;
int sk, err;
@@ -212,7 +212,7 @@ int bnep_if_up(const char *devname)
return 0;
}
-int bnep_if_down(const char *devname)
+static int bnep_if_down(const char *devname)
{
struct ifreq ifr;
int sk, err;
@@ -455,7 +455,7 @@ guint bnep_set_watchdog(struct bnep *b, GIOFunc watchdog, void *data)
return ret;
}
-int bnep_add_to_bridge(const char *devname, const char *bridge)
+static int bnep_add_to_bridge(const char *devname, const char *bridge)
{
int ifindex;
struct ifreq ifr;
@@ -486,7 +486,7 @@ int bnep_add_to_bridge(const char *devname, const char *bridge)
return 0;
}
-int bnep_del_from_bridge(const char *devname, const char *bridge)
+static int bnep_del_from_bridge(const char *devname, const char *bridge)
{
int ifindex = if_nametoindex(devname);
struct ifreq ifr;
@@ -592,3 +592,41 @@ uint16_t bnep_setup_decode(struct bnep_setup_conn_req *req, uint16_t *dst,
return BNEP_SUCCESS;
}
+
+int bnep_server_add(int sk, uint16_t dst, char *bridge, char *iface,
+ const bdaddr_t *addr)
+{
+ if (!bridge || !bridge || !iface || !addr)
+ return -EINVAL;
+
+ if (bnep_connadd(sk, dst, iface) < 0) {
+ error("Can't add connection to the bridge %s: %s(%d)",
+ bridge, strerror(errno), errno);
+ return -errno;
+ }
+
+ if (bnep_add_to_bridge(iface, bridge) < 0) {
+ error("Can't add %s to the bridge %s: %s(%d)",
+ iface, bridge, strerror(errno), errno);
+ bnep_conndel(addr);
+ return -errno;
+ }
+
+ if (bnep_if_up(iface) < 0) {
+ error("Can't up the interface %s: %s(%d)",
+ iface, strerror(errno), errno);
+ return -errno;
+ }
+
+ return 0;
+}
+
+void bnep_server_delete(char *bridge, char *iface, const bdaddr_t *addr)
+{
+ if (!bridge || !iface || !addr)
+ return;
+
+ bnep_del_from_bridge(iface, bridge);
+ bnep_if_down(iface);
+ bnep_conndel(addr);
+}
diff --git a/profiles/network/bnep.h b/profiles/network/bnep.h
index 46199df..3447f6e 100644
--- a/profiles/network/bnep.h
+++ b/profiles/network/bnep.h
@@ -32,12 +32,6 @@ const char *bnep_name(uint16_t id);
struct bnep *bnep_new(int sk, uint16_t local_role, uint16_t remote_role);
void bnep_free(struct bnep *b);
-int bnep_connadd(int sk, uint16_t role, char *dev);
-int bnep_conndel(const bdaddr_t *dst);
-int bnep_if_up(const char *devname);
-int bnep_if_down(const char *devname);
-int bnep_add_to_bridge(const char *devname, const char *bridge);
-int bnep_del_from_bridge(const char *devname, const char *bridge);
typedef void (*bnep_connect_cb) (char *iface, int err, void *data);
int bnep_connect(struct bnep *b, bnep_connect_cb conn_cb, void *data);
@@ -48,3 +42,6 @@ ssize_t bnep_send_ctrl_rsp(int sk, uint8_t type, uint8_t ctrl, uint16_t resp);
uint16_t bnep_setup_chk(uint16_t dst_role, uint16_t src_role);
uint16_t bnep_setup_decode(struct bnep_setup_conn_req *req, uint16_t *dst,
uint16_t *src);
+int bnep_server_add(int sk, uint16_t dst, char *bridge, char *iface,
+ const bdaddr_t *addr);
+void bnep_server_delete(char *bridge, char *iface, const bdaddr_t *addr);
diff --git a/profiles/network/server.c b/profiles/network/server.c
index 73741ec..7cb5a1e 100644
--- a/profiles/network/server.c
+++ b/profiles/network/server.c
@@ -251,35 +251,6 @@ static sdp_record_t *server_record_new(const char *name, uint16_t id)
return record;
}
-static int server_connadd(struct network_server *ns,
- struct network_session *session,
- uint16_t dst_role)
-{
- char devname[16];
- int err, nsk;
-
- nsk = g_io_channel_unix_get_fd(session->io);
- err = bnep_connadd(nsk, dst_role, devname);
- if (err < 0)
- return err;
-
- info("Added new connection: %s", devname);
-
- if (bnep_add_to_bridge(devname, ns->bridge) < 0) {
- error("Can't add %s to the bridge %s: %s(%d)",
- devname, ns->bridge, strerror(errno), errno);
- return -EPERM;
- }
-
- bnep_if_up(devname);
-
- strncpy(session->dev, devname, sizeof(devname));
-
- ns->sessions = g_slist_append(ns->sessions, session);
-
- return 0;
-}
-
static void session_free(void *data)
{
struct network_session *session = data;
@@ -377,7 +348,8 @@ static gboolean bnep_setup(GIOChannel *chan,
goto reply;
}
- if (server_connadd(ns, na->setup, dst_role) < 0)
+ if (bnep_server_add(sk, dst_role, ns->bridge, na->setup->dev,
+ &na->setup->dst) < 0)
goto reply;
na->setup = NULL;
@@ -524,10 +496,7 @@ static void server_remove_sessions(struct network_server *ns)
if (*session->dev == '\0')
continue;
- bnep_del_from_bridge(session->dev, ns->bridge);
- bnep_if_down(session->dev);
-
- bnep_conndel(&session->dst);
+ bnep_server_delete(ns->bridge, session->dev, &session->dst);
}
g_slist_free_full(ns->sessions, session_free);
--
1.8.3.2
^ permalink raw reply related
* [PATCH_v5 4/5] bnep: Refactored bnep connect and disconnect calls
From: Ravi kumar Veeramally @ 2013-12-19 8:48 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Ravi kumar Veeramally
In-Reply-To: <1387442933-20681-1-git-send-email-ravikumar.veeramally@linux.intel.com>
Refactored bnep connect and disconnect calls to simplify and
keeping bnep related functionality behind curtains.
Provided bnep struct globally. bnep_connect calls takes
care of bnep_setup until interface up then connect callback
will be called. Provided bnep_set_watchdog. When interface is
up then only set watchdog. bnep_disconnect should be called
only when iface is up/connected.
---
android/pan.c | 50 ++++++++++++------------
profiles/network/bnep.c | 91 +++++++++++++++++++++++++++----------------
profiles/network/bnep.h | 8 ++--
profiles/network/connection.c | 42 +++++++++++++-------
4 files changed, 114 insertions(+), 77 deletions(-)
diff --git a/android/pan.c b/android/pan.c
index 187953b..2537114 100644
--- a/android/pan.c
+++ b/android/pan.c
@@ -55,6 +55,7 @@ struct pan_device {
uint8_t role;
GIOChannel *io;
guint watch;
+ struct bnep *bnep_conn;
};
static int device_cmp(gconstpointer s, gconstpointer user_data)
@@ -67,6 +68,8 @@ static int device_cmp(gconstpointer s, gconstpointer user_data)
static void pan_device_free(struct pan_device *dev)
{
+ DBG("");
+
if (dev->watch > 0) {
g_source_remove(dev->watch);
dev->watch = 0;
@@ -77,6 +80,7 @@ static void pan_device_free(struct pan_device *dev)
dev->io = NULL;
}
+ bnep_free(dev->bnep_conn);
devices = g_slist_remove(devices, dev);
g_free(dev);
@@ -92,7 +96,6 @@ static void bt_pan_notify_conn_state(struct pan_device *dev, uint8_t state)
if (dev->conn_state == state)
return;
- dev->conn_state = state;
ba2str(&dev->dst, addr);
DBG("device %s state %u", addr, state);
@@ -104,8 +107,16 @@ static void bt_pan_notify_conn_state(struct pan_device *dev, uint8_t state)
ipc_send_notif(HAL_SERVICE_ID_PAN, HAL_EV_PAN_CONN_STATE, sizeof(ev),
&ev);
- if (dev->conn_state == HAL_PAN_STATE_DISCONNECTED)
- pan_device_free(dev);
+
+ if (dev->conn_state == HAL_PAN_STATE_CONNECTED)
+ bnep_disconnect(dev->bnep_conn);
+
+ dev->conn_state = state;
+
+ if (state != HAL_PAN_STATE_DISCONNECTED)
+ return;
+
+ pan_device_free(dev);
}
static void bt_pan_notify_ctrl_state(struct pan_device *dev, uint8_t state)
@@ -131,14 +142,12 @@ static gboolean bnep_watchdog_cb(GIOChannel *chan, GIOCondition cond,
DBG("%s disconnected", dev->iface);
- bnep_if_down(dev->iface);
- bnep_conndel(&dev->dst);
bt_pan_notify_conn_state(dev, HAL_PAN_STATE_DISCONNECTED);
return FALSE;
}
-static void bnep_conn_cb(GIOChannel *chan, char *iface, int err, void *data)
+static void bnep_conn_cb(char *iface, int err, void *data)
{
struct pan_device *dev = data;
@@ -146,28 +155,22 @@ static void bnep_conn_cb(GIOChannel *chan, char *iface, int err, void *data)
if (err < 0) {
error("bnep connect req failed: %s", strerror(-err));
- bnep_conndel(&dev->dst);
bt_pan_notify_conn_state(dev, HAL_PAN_STATE_DISCONNECTED);
return;
}
- memcpy(dev->iface, iface, sizeof(dev->iface));
-
- DBG("%s connected", dev->iface);
+ DBG("%s connected", iface);
+ memcpy(dev->iface, iface, sizeof(dev->iface));
bt_pan_notify_ctrl_state(dev, HAL_PAN_CTRL_ENABLED);
bt_pan_notify_conn_state(dev, HAL_PAN_STATE_CONNECTED);
-
- dev->watch = g_io_add_watch(chan, G_IO_ERR | G_IO_HUP | G_IO_NVAL,
- bnep_watchdog_cb, dev);
- g_io_channel_unref(dev->io);
- dev->io = NULL;
+ dev->watch = bnep_set_watchdog(dev->bnep_conn, bnep_watchdog_cb, dev);
}
static void connect_cb(GIOChannel *chan, GError *err, gpointer data)
{
struct pan_device *dev = data;
- uint16_t src, dst;
+ uint16_t l_role, r_role;
int perr, sk;
DBG("");
@@ -177,11 +180,13 @@ static void connect_cb(GIOChannel *chan, GError *err, gpointer data)
goto fail;
}
- src = (local_role == HAL_PAN_ROLE_NAP) ? BNEP_SVC_NAP : BNEP_SVC_PANU;
- dst = (dev->role == HAL_PAN_ROLE_NAP) ? BNEP_SVC_NAP : BNEP_SVC_PANU;
- sk = g_io_channel_unix_get_fd(dev->io);
+ l_role = (local_role == HAL_PAN_ROLE_NAP) ? BNEP_SVC_NAP :
+ BNEP_SVC_PANU;
+ r_role = (dev->role == HAL_PAN_ROLE_NAP) ? BNEP_SVC_NAP : BNEP_SVC_PANU;
- perr = bnep_connect(sk, src, dst, bnep_conn_cb, dev);
+ sk = g_io_channel_unix_get_fd(dev->io);
+ dev->bnep_conn = bnep_new(sk, l_role, r_role);
+ perr = bnep_connect(dev->bnep_conn, bnep_conn_cb, dev);
if (perr < 0) {
error("bnep connect req failed: %s", strerror(-perr));
goto fail;
@@ -288,11 +293,6 @@ static void bt_pan_disconnect(const void *buf, uint16_t len)
if (dev->io)
g_io_channel_shutdown(dev->io, TRUE, NULL);
- if (dev->conn_state == HAL_PAN_STATE_CONNECTED) {
- bnep_if_down(dev->iface);
- bnep_conndel(&dst);
- }
-
bt_pan_notify_conn_state(dev, HAL_PAN_STATE_DISCONNECTING);
status = HAL_STATUS_SUCCESS;
diff --git a/profiles/network/bnep.c b/profiles/network/bnep.c
index f3ed63b..b7c3835 100644
--- a/profiles/network/bnep.c
+++ b/profiles/network/bnep.c
@@ -39,6 +39,7 @@
#include <bluetooth/bluetooth.h>
#include <bluetooth/l2cap.h>
#include <bluetooth/bnep.h>
+#include <btio/btio.h>
#include <glib.h>
@@ -71,25 +72,15 @@ struct bnep {
GIOChannel *io;
uint16_t src;
uint16_t dst;
+ bdaddr_t dst_addr;
+ char iface[16];
guint attempts;
guint setup_to;
void *data;
bnep_connect_cb conn_cb;
+ guint watch;
};
-static void free_bnep_connect(struct bnep *b)
-{
- if (!b)
- return;
-
- if (b->io) {
- g_io_channel_unref(b->io);
- b->io = NULL;
- }
-
- g_free(b);
-}
-
uint16_t bnep_service_id(const char *svc)
{
int i;
@@ -278,12 +269,11 @@ static gboolean bnep_setup_cb(GIOChannel *chan, GIOCondition cond,
struct bnep_control_rsp *rsp;
struct timeval timeo;
char pkt[BNEP_MTU];
- char iface[16];
ssize_t r;
int sk;
if (cond & G_IO_NVAL)
- goto failed;
+ return FALSE;
if (b->setup_to > 0) {
g_source_remove(b->setup_to);
@@ -335,24 +325,23 @@ static gboolean bnep_setup_cb(GIOChannel *chan, GIOCondition cond,
setsockopt(sk, SOL_SOCKET, SO_RCVTIMEO, &timeo, sizeof(timeo));
sk = g_io_channel_unix_get_fd(b->io);
- if (bnep_connadd(sk, b->src, iface)) {
+ if (bnep_connadd(sk, b->src, b->iface)) {
error("bnep conn could not be added");
goto failed;
}
- if (bnep_if_up(iface)) {
- error("could not up %s", iface);
+ if (bnep_if_up(b->iface)) {
+ error("could not up %s", b->iface);
+ bnep_conndel(&b->dst_addr);
goto failed;
}
- b->conn_cb(chan, iface, 0, b->data);
- free_bnep_connect(b);
+ b->conn_cb(b->iface, 0, b->data);
return FALSE;
failed:
- b->conn_cb(NULL, NULL, -EIO, b->data);
- free_bnep_connect(b);
+ b->conn_cb(NULL, -EIO, b->data);
return FALSE;
}
@@ -396,40 +385,76 @@ static gboolean bnep_conn_req_to(gpointer user_data)
return TRUE;
}
- b->conn_cb(NULL, NULL, -ETIMEDOUT, b->data);
- free_bnep_connect(b);
+ b->conn_cb(NULL, -ETIMEDOUT, b->data);
return FALSE;
}
-int bnep_connect(int sk, uint16_t src, uint16_t dst, bnep_connect_cb conn_cb,
- void *data)
+int bnep_connect(struct bnep *b, bnep_connect_cb conn_cb, void *data)
{
- struct bnep *b;
+ GError *gerr = NULL;
int err;
- if (!conn_cb)
+ if (!b || !conn_cb)
return -EINVAL;
- b = g_new0(struct bnep, 1);
- b->io = g_io_channel_unix_new(sk);
b->attempts = 0;
- b->src = src;
- b->dst = dst;
b->conn_cb = conn_cb;
b->data = data;
+ bt_io_get(b->io, &gerr, BT_IO_OPT_DEST_BDADDR, &b->dst_addr,
+ BT_IO_OPT_INVALID);
+ if (gerr) {
+ error("%s", gerr->message);
+ g_error_free(gerr);
+ return -EINVAL;
+ }
+
err = bnep_setup_conn_req(b);
if (err < 0)
return err;
b->setup_to = g_timeout_add_seconds(CON_SETUP_TO,
bnep_conn_req_to, b);
- g_io_add_watch(b->io, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
+ b->watch = g_io_add_watch(b->io,
+ G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
bnep_setup_cb, b);
return 0;
}
+void bnep_disconnect(struct bnep *b)
+{
+ if (!b)
+ return;
+
+ if (b->io) {
+ g_io_channel_unref(b->io);
+ b->io = NULL;
+ }
+
+ if (b->watch) {
+ g_source_remove(b->watch);
+ b->watch = 0;
+ }
+
+ bnep_if_down(b->iface);
+ bnep_conndel(&b->dst_addr);
+}
+
+guint bnep_set_watchdog(struct bnep *b, GIOFunc watchdog, void *data)
+{
+ guint ret = 0;
+
+ if (!b)
+ return ret;
+
+ if (b->io)
+ ret = g_io_add_watch(b->io, G_IO_ERR | G_IO_HUP | G_IO_NVAL,
+ watchdog, data);
+
+ return ret;
+}
+
int bnep_add_to_bridge(const char *devname, const char *bridge)
{
int ifindex;
diff --git a/profiles/network/bnep.h b/profiles/network/bnep.h
index 091a7f2..46199df 100644
--- a/profiles/network/bnep.h
+++ b/profiles/network/bnep.h
@@ -39,10 +39,10 @@ int bnep_if_down(const char *devname);
int bnep_add_to_bridge(const char *devname, const char *bridge);
int bnep_del_from_bridge(const char *devname, const char *bridge);
-typedef void (*bnep_connect_cb) (GIOChannel *chan, char *iface, int err,
- void *data);
-int bnep_connect(int sk, uint16_t src, uint16_t dst, bnep_connect_cb conn_cb,
- void *data);
+typedef void (*bnep_connect_cb) (char *iface, int err, void *data);
+int bnep_connect(struct bnep *b, bnep_connect_cb conn_cb, void *data);
+guint bnep_set_watchdog(struct bnep *b, GIOFunc watchdog, void *data);
+void bnep_disconnect(struct bnep *b);
ssize_t bnep_send_ctrl_rsp(int sk, uint8_t type, uint8_t ctrl, uint16_t resp);
uint16_t bnep_setup_chk(uint16_t dst_role, uint16_t src_role);
diff --git a/profiles/network/connection.c b/profiles/network/connection.c
index fb3e1ce..f1a44e9 100644
--- a/profiles/network/connection.c
+++ b/profiles/network/connection.c
@@ -72,6 +72,8 @@ struct network_conn {
guint dc_id;
struct network_peer *peer;
DBusMessage *connect;
+ struct bnep *bnep_conn;
+ guint watch;
};
static GSList *peers = NULL;
@@ -126,11 +128,19 @@ static gboolean bnep_watchdog_cb(GIOChannel *chan, GIOCondition cond,
info("%s disconnected", nc->dev);
- bnep_if_down(nc->dev);
nc->state = DISCONNECTED;
memset(nc->dev, 0, sizeof(nc->dev));
strcpy(nc->dev, "bnep%d");
+ bnep_free(nc->bnep_conn);
+ nc->bnep_conn = NULL;
+
+ if (nc->io) {
+ g_io_channel_shutdown(nc->io, TRUE, NULL);
+ g_io_channel_unref(nc->io);
+ nc->io = NULL;
+ }
+
return FALSE;
}
@@ -158,9 +168,17 @@ static void cancel_connection(struct network_conn *nc, int err)
if (nc->connect)
local_connect_cb(nc, err);
- g_io_channel_shutdown(nc->io, TRUE, NULL);
- g_io_channel_unref(nc->io);
- nc->io = NULL;
+ if (nc->io) {
+ g_io_channel_shutdown(nc->io, TRUE, NULL);
+ g_io_channel_unref(nc->io);
+ nc->io = NULL;
+ }
+
+ if (nc->state == CONNECTED)
+ bnep_disconnect(nc->bnep_conn);
+
+ bnep_free(nc->bnep_conn);
+ nc->bnep_conn = NULL;
nc->state = DISCONNECTED;
}
@@ -169,11 +187,7 @@ static void connection_destroy(DBusConnection *conn, void *user_data)
{
struct network_conn *nc = user_data;
- if (nc->state == CONNECTED) {
- bnep_if_down(nc->dev);
- bnep_conndel(device_get_address(nc->peer->device));
- } else if (nc->io)
- cancel_connection(nc, -EIO);
+ cancel_connection(nc, -EIO);
}
static void disconnect_cb(struct btd_device *device, gboolean removal,
@@ -186,7 +200,7 @@ static void disconnect_cb(struct btd_device *device, gboolean removal,
connection_destroy(NULL, user_data);
}
-static void bnep_conn_cb(GIOChannel *chan, char *iface, int err, void *data)
+static void bnep_conn_cb(char *iface, int err, void *data)
{
struct network_conn *nc = data;
const char *path;
@@ -220,10 +234,7 @@ static void bnep_conn_cb(GIOChannel *chan, char *iface, int err, void *data)
nc->state = CONNECTED;
nc->dc_id = device_add_disconnect_watch(nc->peer->device, disconnect_cb,
nc, NULL);
- g_io_add_watch(chan, G_IO_ERR | G_IO_HUP | G_IO_NVAL,
- bnep_watchdog_cb, nc);
- g_io_channel_unref(nc->io);
- nc->io = NULL;
+ nc->watch = bnep_set_watchdog(nc->bnep_conn, bnep_watchdog_cb, nc);
return;
@@ -242,7 +253,8 @@ static void connect_cb(GIOChannel *chan, GError *err, gpointer data)
}
sk = g_io_channel_unix_get_fd(nc->io);
- perr = bnep_connect(sk, BNEP_SVC_PANU, nc->id, bnep_conn_cb, nc);
+ nc->bnep_conn = bnep_new(sk, BNEP_SVC_PANU, nc->id);
+ perr = bnep_connect(nc->bnep_conn, bnep_conn_cb, nc);
if (perr < 0) {
error("bnep connect(): %s (%d)", strerror(-perr), -perr);
goto failed;
--
1.8.3.2
^ permalink raw reply related
* [PATCH_v5 3/5] bnep: Add bnep_new and bnep_free api's
From: Ravi kumar Veeramally @ 2013-12-19 8:48 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Ravi kumar Veeramally
In-Reply-To: <1387442933-20681-1-git-send-email-ravikumar.veeramally@linux.intel.com>
Refacoring connect and disconnect mechanisms. It would be more
convinient for caller to maintain just bnep connection reference
and delete whenever it is not required.
---
profiles/network/bnep.c | 25 +++++++++++++++++++++++++
profiles/network/bnep.h | 4 ++++
2 files changed, 29 insertions(+)
diff --git a/profiles/network/bnep.c b/profiles/network/bnep.c
index 02e2647..f3ed63b 100644
--- a/profiles/network/bnep.c
+++ b/profiles/network/bnep.c
@@ -246,6 +246,31 @@ int bnep_if_down(const char *devname)
return 0;
}
+struct bnep *bnep_new(int sk, uint16_t local_role, uint16_t remote_role)
+{
+ struct bnep *b;
+
+ b = g_new0(struct bnep, 1);
+ b->io = g_io_channel_unix_new(sk);
+ b->src = local_role;
+ b->dst = remote_role;
+
+ return b;
+}
+
+void bnep_free(struct bnep *b)
+{
+ if (!b)
+ return;
+
+ if (b->io) {
+ g_io_channel_unref(b->io);
+ b->io = NULL;
+ }
+
+ g_free(b);
+}
+
static gboolean bnep_setup_cb(GIOChannel *chan, GIOCondition cond,
gpointer data)
{
diff --git a/profiles/network/bnep.h b/profiles/network/bnep.h
index dd22c40..091a7f2 100644
--- a/profiles/network/bnep.h
+++ b/profiles/network/bnep.h
@@ -21,6 +21,8 @@
*
*/
+struct bnep;
+
int bnep_init(void);
int bnep_cleanup(void);
@@ -28,6 +30,8 @@ uint16_t bnep_service_id(const char *svc);
const char *bnep_uuid(uint16_t id);
const char *bnep_name(uint16_t id);
+struct bnep *bnep_new(int sk, uint16_t local_role, uint16_t remote_role);
+void bnep_free(struct bnep *b);
int bnep_connadd(int sk, uint16_t role, char *dev);
int bnep_conndel(const bdaddr_t *dst);
int bnep_if_up(const char *devname);
--
1.8.3.2
^ permalink raw reply related
* [PATCH_v5 2/5] bnep: Rename struct bnep_conn to struct bnep for better readability
From: Ravi kumar Veeramally @ 2013-12-19 8:48 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Ravi kumar Veeramally
In-Reply-To: <1387442933-20681-1-git-send-email-ravikumar.veeramally@linux.intel.com>
---
profiles/network/bnep.c | 80 ++++++++++++++++++++++++-------------------------
1 file changed, 40 insertions(+), 40 deletions(-)
diff --git a/profiles/network/bnep.c b/profiles/network/bnep.c
index 08037e6..02e2647 100644
--- a/profiles/network/bnep.c
+++ b/profiles/network/bnep.c
@@ -67,7 +67,7 @@ struct __service_16 {
uint16_t src;
} __attribute__ ((packed));
-struct bnep_conn {
+struct bnep {
GIOChannel *io;
uint16_t src;
uint16_t dst;
@@ -77,17 +77,17 @@ struct bnep_conn {
bnep_connect_cb conn_cb;
};
-static void free_bnep_connect(struct bnep_conn *bc)
+static void free_bnep_connect(struct bnep *b)
{
- if (!bc)
+ if (!b)
return;
- if (bc->io) {
- g_io_channel_unref(bc->io);
- bc->io = NULL;
+ if (b->io) {
+ g_io_channel_unref(b->io);
+ b->io = NULL;
}
- g_free(bc);
+ g_free(b);
}
uint16_t bnep_service_id(const char *svc)
@@ -249,7 +249,7 @@ int bnep_if_down(const char *devname)
static gboolean bnep_setup_cb(GIOChannel *chan, GIOCondition cond,
gpointer data)
{
- struct bnep_conn *bc = data;
+ struct bnep *b = data;
struct bnep_control_rsp *rsp;
struct timeval timeo;
char pkt[BNEP_MTU];
@@ -260,9 +260,9 @@ static gboolean bnep_setup_cb(GIOChannel *chan, GIOCondition cond,
if (cond & G_IO_NVAL)
goto failed;
- if (bc->setup_to > 0) {
- g_source_remove(bc->setup_to);
- bc->setup_to = 0;
+ if (b->setup_to > 0) {
+ g_source_remove(b->setup_to);
+ b->setup_to = 0;
}
if (cond & (G_IO_HUP | G_IO_ERR)) {
@@ -309,8 +309,8 @@ static gboolean bnep_setup_cb(GIOChannel *chan, GIOCondition cond,
timeo.tv_sec = 0;
setsockopt(sk, SOL_SOCKET, SO_RCVTIMEO, &timeo, sizeof(timeo));
- sk = g_io_channel_unix_get_fd(bc->io);
- if (bnep_connadd(sk, bc->src, iface)) {
+ sk = g_io_channel_unix_get_fd(b->io);
+ if (bnep_connadd(sk, b->src, iface)) {
error("bnep conn could not be added");
goto failed;
}
@@ -320,19 +320,19 @@ static gboolean bnep_setup_cb(GIOChannel *chan, GIOCondition cond,
goto failed;
}
- bc->conn_cb(chan, iface, 0, bc->data);
- free_bnep_connect(bc);
+ b->conn_cb(chan, iface, 0, b->data);
+ free_bnep_connect(b);
return FALSE;
failed:
- bc->conn_cb(NULL, NULL, -EIO, bc->data);
- free_bnep_connect(bc);
+ b->conn_cb(NULL, NULL, -EIO, b->data);
+ free_bnep_connect(b);
return FALSE;
}
-static int bnep_setup_conn_req(struct bnep_conn *bc)
+static int bnep_setup_conn_req(struct bnep *b)
{
struct bnep_setup_conn_req *req;
struct __service_16 *s;
@@ -345,34 +345,34 @@ static int bnep_setup_conn_req(struct bnep_conn *bc)
req->ctrl = BNEP_SETUP_CONN_REQ;
req->uuid_size = 2; /* 16bit UUID */
s = (void *) req->service;
- s->src = htons(bc->src);
- s->dst = htons(bc->dst);
+ s->src = htons(b->src);
+ s->dst = htons(b->dst);
- fd = g_io_channel_unix_get_fd(bc->io);
+ fd = g_io_channel_unix_get_fd(b->io);
if (write(fd, pkt, sizeof(*req) + sizeof(*s)) < 0) {
error("bnep connection req send failed: %s", strerror(errno));
return -errno;
}
- bc->attempts++;
+ b->attempts++;
return 0;
}
static gboolean bnep_conn_req_to(gpointer user_data)
{
- struct bnep_conn *bc = user_data;
+ struct bnep *b = user_data;
- if (bc->attempts == CON_SETUP_RETRIES) {
+ if (b->attempts == CON_SETUP_RETRIES) {
error("Too many bnep connection attempts");
} else {
error("bnep connection setup TO, retrying...");
- if (bnep_setup_conn_req(bc) == 0)
+ if (bnep_setup_conn_req(b) == 0)
return TRUE;
}
- bc->conn_cb(NULL, NULL, -ETIMEDOUT, bc->data);
- free_bnep_connect(bc);
+ b->conn_cb(NULL, NULL, -ETIMEDOUT, b->data);
+ free_bnep_connect(b);
return FALSE;
}
@@ -380,28 +380,28 @@ static gboolean bnep_conn_req_to(gpointer user_data)
int bnep_connect(int sk, uint16_t src, uint16_t dst, bnep_connect_cb conn_cb,
void *data)
{
- struct bnep_conn *bc;
+ struct bnep *b;
int err;
if (!conn_cb)
return -EINVAL;
- bc = g_new0(struct bnep_conn, 1);
- bc->io = g_io_channel_unix_new(sk);
- bc->attempts = 0;
- bc->src = src;
- bc->dst = dst;
- bc->conn_cb = conn_cb;
- bc->data = data;
+ b = g_new0(struct bnep, 1);
+ b->io = g_io_channel_unix_new(sk);
+ b->attempts = 0;
+ b->src = src;
+ b->dst = dst;
+ b->conn_cb = conn_cb;
+ b->data = data;
- err = bnep_setup_conn_req(bc);
+ err = bnep_setup_conn_req(b);
if (err < 0)
return err;
- bc->setup_to = g_timeout_add_seconds(CON_SETUP_TO,
- bnep_conn_req_to, bc);
- g_io_add_watch(bc->io, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
- bnep_setup_cb, bc);
+ b->setup_to = g_timeout_add_seconds(CON_SETUP_TO,
+ bnep_conn_req_to, b);
+ g_io_add_watch(b->io, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
+ bnep_setup_cb, b);
return 0;
}
--
1.8.3.2
^ permalink raw reply related
* [PATCH_v5 1/5] android/pan: shutdown io channel on disconnect call
From: Ravi kumar Veeramally @ 2013-12-19 8:48 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Ravi kumar Veeramally
Shutdown io channel and send DISCONNECTING notification and send
DISCONNECTED notification and free the device on callback.
---
android/pan.c | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/android/pan.c b/android/pan.c
index b83f534..187953b 100644
--- a/android/pan.c
+++ b/android/pan.c
@@ -284,14 +284,16 @@ static void bt_pan_disconnect(const void *buf, uint16_t len)
}
dev = l->data;
- if (dev->watch) {
- g_source_remove(dev->watch);
- dev->watch = 0;
+
+ if (dev->io)
+ g_io_channel_shutdown(dev->io, TRUE, NULL);
+
+ if (dev->conn_state == HAL_PAN_STATE_CONNECTED) {
+ bnep_if_down(dev->iface);
+ bnep_conndel(&dst);
}
- bnep_if_down(dev->iface);
- bnep_conndel(&dst);
- bt_pan_notify_conn_state(dev, HAL_PAN_STATE_DISCONNECTED);
+ bt_pan_notify_conn_state(dev, HAL_PAN_STATE_DISCONNECTING);
status = HAL_STATUS_SUCCESS;
failed:
--
1.8.3.2
^ permalink raw reply related
* Re: [PATCH_v4 3/7] android/pan: shutdown io channel on disconnect call
From: Ravi kumar Veeramally @ 2013-12-19 8:48 UTC (permalink / raw)
To: linux-bluetooth, johan.hedberg
In-Reply-To: <20131219081452.GB31549@x220.p-661hnu-f1>
Hi Johan,
On 19.12.2013 10:14, Johan Hedberg wrote:
> Hi Ravi,
>
> On Wed, Dec 18, 2013, Ravi kumar Veeramally wrote:
>> Shutdown io channel and send DISCONNECTING notification and send
>> DISCONNECTED notification and free the device on callback.
>> ---
>> android/pan.c | 20 ++++++++++----------
>> 1 file changed, 10 insertions(+), 10 deletions(-)
> I've applied the first two patches, but one thing with this one:
>
>> diff --git a/android/pan.c b/android/pan.c
>> index b83f534..f64b09a 100644
>> --- a/android/pan.c
>> +++ b/android/pan.c
>> @@ -269,7 +269,7 @@ static void bt_pan_disconnect(const void *buf, uint16_t len)
>> {
>> const struct hal_cmd_pan_disconnect *cmd = buf;
>> struct pan_device *dev;
>> - uint8_t status;
>> + uint8_t status = HAL_STATUS_FAILED;
>> GSList *l;
>> bdaddr_t dst;
>>
>> @@ -278,20 +278,20 @@ static void bt_pan_disconnect(const void *buf, uint16_t len)
>> android2bdaddr(&cmd->bdaddr, &dst);
>>
>> l = g_slist_find_custom(devices, &dst, device_cmp);
>> - if (!l) {
>> - status = HAL_STATUS_FAILED;
>> + if (!l)
>> goto failed;
> Since we in general try to avoid initializations upon declaration I'd
> keep the status = HAL_STATUS_FAILED here. Even if it would be ok to move
> it it shouldn't be in this patch since it's unrelated.
Ok, make sense. I'll send you updated patch set from 3-7 in a moment.
Thanks,
Ravi.
^ permalink raw reply
* Re: [PATCH 1/4] android/bluetooth: Add initial support for permanent storage
From: Szymon Janc @ 2013-12-19 8:35 UTC (permalink / raw)
To: Johan Hedberg; +Cc: linux-bluetooth
In-Reply-To: <20131219082907.GA2549@x220.p-661hnu-f1>
Hi Johan,
> Hi Szymon,
>
> On Wed, Dec 18, 2013, Szymon Janc wrote:
> > +static void store_adapter_config(void)
> > +{
> > + GKeyFile *key_file;
> > + gsize length = 0;
> > + char addr[18];
> > + char *data;
> > +
> > + key_file = g_key_file_new();
> > +
> > + if (!g_key_file_load_from_file(key_file, ANDROID_STORAGEDIR"/settings",
> > + 0, NULL)) {
> > + int fd = open(ANDROID_STORAGEDIR"/settings", O_CREAT, 0600);
> > + if (fd < 0) {
> > + error("Failed to create adapter config file: %d (%s)",
> > + errno, strerror(errno));
> > + return;
> > + }
> > +
> > + close(fd);
> > + }
> > +
> > + ba2str(&adapter.bdaddr, addr);
> > +
> > + g_key_file_set_string(key_file, "General", "Address", addr);
> > + g_key_file_set_string(key_file, "General", "Name", adapter.name);
> > + g_key_file_set_integer(key_file, "General", "DiscoverableTimeout",
> > + adapter.discoverable_timeout);
> > +
> > + data = g_key_file_to_data(key_file, &length, NULL);
> > +
> > + g_file_set_contents(ANDROID_STORAGEDIR"/settings", data, length, NULL);
>
> The whole open(..., O_CREAT, ...) trick you do seems completely
> unnecessary as g_key_file_to_data will create the file if it doesn't
> exist. Instead, if you want to log an error you'd need to check if
> g_key_file_contents failed or not. Adding a GError into the mix and
> logging the exact error message would be even better.
This was done only to make sure proper permissions are used for file. Since
glib doens't offer any API (at least I couldn't find any) for that in g_file_*
(other than wrappers to standard unix calls)
--
BR
Szymon Janc
^ permalink raw reply
* Re: [PATCH 1/4] android/bluetooth: Add initial support for permanent storage
From: Johan Hedberg @ 2013-12-19 8:29 UTC (permalink / raw)
To: Szymon Janc; +Cc: linux-bluetooth
In-Reply-To: <1387375558-17976-2-git-send-email-szymon.janc@tieto.com>
Hi Szymon,
On Wed, Dec 18, 2013, Szymon Janc wrote:
> +static void store_adapter_config(void)
> +{
> + GKeyFile *key_file;
> + gsize length = 0;
> + char addr[18];
> + char *data;
> +
> + key_file = g_key_file_new();
> +
> + if (!g_key_file_load_from_file(key_file, ANDROID_STORAGEDIR"/settings",
> + 0, NULL)) {
> + int fd = open(ANDROID_STORAGEDIR"/settings", O_CREAT, 0600);
> + if (fd < 0) {
> + error("Failed to create adapter config file: %d (%s)",
> + errno, strerror(errno));
> + return;
> + }
> +
> + close(fd);
> + }
> +
> + ba2str(&adapter.bdaddr, addr);
> +
> + g_key_file_set_string(key_file, "General", "Address", addr);
> + g_key_file_set_string(key_file, "General", "Name", adapter.name);
> + g_key_file_set_integer(key_file, "General", "DiscoverableTimeout",
> + adapter.discoverable_timeout);
> +
> + data = g_key_file_to_data(key_file, &length, NULL);
> +
> + g_file_set_contents(ANDROID_STORAGEDIR"/settings", data, length, NULL);
The whole open(..., O_CREAT, ...) trick you do seems completely
unnecessary as g_key_file_to_data will create the file if it doesn't
exist. Instead, if you want to log an error you'd need to check if
g_key_file_contents failed or not. Adding a GError into the mix and
logging the exact error message would be even better.
Johan
^ permalink raw reply
* Re: [PATCH] android/pts: Add PICS, PIXITs and PTS for L2CAP
From: Johan Hedberg @ 2013-12-19 8:21 UTC (permalink / raw)
To: Sebastian Chlad; +Cc: linux-bluetooth, Sebastian Chlad
In-Reply-To: <1387395146-28084-1-git-send-email-sebastianx.chlad@intel.com>
Hi Sebastian,
On Wed, Dec 18, 2013, Sebastian Chlad wrote:
> This allows better tracking of the current state of implementation
> ---
> android/pics-l2cap.txt | 157 ++++++++++++++++++++++++++
> android/pixit-l2cap.txt | 39 +++++++
> android/pts-l2cap.txt | 293 ++++++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 489 insertions(+)
> create mode 100644 android/pics-l2cap.txt
> create mode 100644 android/pixit-l2cap.txt
> create mode 100644 android/pts-l2cap.txt
Looks otherwise fine to me, but are you've forgotten to add these to
EXTRA_DIST in android/Makefile.am. Otherwise the files would not get
included in the next release tarball we make.
Johan
^ permalink raw reply
* Re: [PATCH 1/2] android/tester: Add Socket test close and listen
From: Johan Hedberg @ 2013-12-19 8:18 UTC (permalink / raw)
To: Andrei Emeltchenko; +Cc: linux-bluetooth
In-Reply-To: <1387379717-1457-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
Hi Andrei,
On Wed, Dec 18, 2013, Andrei Emeltchenko wrote:
> This test the situation when Android close file descriptor we passed to
> it and try to listen() again.
> ---
> android/android-tester.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 55 insertions(+)
>
> diff --git a/android/android-tester.c b/android/android-tester.c
> index 8a2861e..cb8fb4e 100644
> --- a/android/android-tester.c
> +++ b/android/android-tester.c
> @@ -1141,6 +1141,57 @@ clean:
> close(sock_fd);
> }
>
> +static void test_listen_close(const void *test_data)
> +{
> + struct test_data *data = tester_get_data();
> + const struct socket_data *test = data->test_data;
> + bt_status_t status;
> + int sock_fd = -1;
> +
> + status = data->if_sock->listen(test->sock_type,
> + test->service_name, test->service_uuid,
> + test->channel, &sock_fd, test->flags);
> + if (status != test->expected_status) {
> + tester_test_failed();
> + goto clean;
> + }
> +
> + /* Check that file descriptor is valid */
> + if (status == BT_STATUS_SUCCESS && fcntl(sock_fd, F_GETFD) == -1) {
We usually check for failures like this with < 0 instead of == -1.
> + status = data->if_sock->listen(test->sock_type,
> + test->service_name, test->service_uuid,
> + test->channel, &sock_fd, test->flags);
> + if (status != test->expected_status) {
> + tester_test_failed();
> + goto clean;
> + }
You've got many different conditions that can trigger
tester_test_failed but no tester_warn() logs for each one to make
debugging easy if these new tests start failing. Please add those.
Otherwise once there's a regression it's going to be a real pain for you
to track down exactly what's broken.
Johan
^ permalink raw reply
* Re: [PATCH_v4 3/7] android/pan: shutdown io channel on disconnect call
From: Johan Hedberg @ 2013-12-19 8:14 UTC (permalink / raw)
To: Ravi kumar Veeramally; +Cc: linux-bluetooth
In-Reply-To: <1387378396-6259-3-git-send-email-ravikumar.veeramally@linux.intel.com>
Hi Ravi,
On Wed, Dec 18, 2013, Ravi kumar Veeramally wrote:
> Shutdown io channel and send DISCONNECTING notification and send
> DISCONNECTED notification and free the device on callback.
> ---
> android/pan.c | 20 ++++++++++----------
> 1 file changed, 10 insertions(+), 10 deletions(-)
I've applied the first two patches, but one thing with this one:
> diff --git a/android/pan.c b/android/pan.c
> index b83f534..f64b09a 100644
> --- a/android/pan.c
> +++ b/android/pan.c
> @@ -269,7 +269,7 @@ static void bt_pan_disconnect(const void *buf, uint16_t len)
> {
> const struct hal_cmd_pan_disconnect *cmd = buf;
> struct pan_device *dev;
> - uint8_t status;
> + uint8_t status = HAL_STATUS_FAILED;
> GSList *l;
> bdaddr_t dst;
>
> @@ -278,20 +278,20 @@ static void bt_pan_disconnect(const void *buf, uint16_t len)
> android2bdaddr(&cmd->bdaddr, &dst);
>
> l = g_slist_find_custom(devices, &dst, device_cmp);
> - if (!l) {
> - status = HAL_STATUS_FAILED;
> + if (!l)
> goto failed;
Since we in general try to avoid initializations upon declaration I'd
keep the status = HAL_STATUS_FAILED here. Even if it would be ok to move
it it shouldn't be in this patch since it's unrelated.
Johan
^ permalink raw reply
* Re: [PATCH 2/3] android/socket: Connect directly to RFCOMM chan is uuid is zero
From: Johan Hedberg @ 2013-12-19 8:09 UTC (permalink / raw)
To: Andrei Emeltchenko; +Cc: linux-bluetooth
In-Reply-To: <1387376336-17092-3-git-send-email-Andrei.Emeltchenko.news@gmail.com>
Hi Andrei,
On Wed, Dec 18, 2013, Andrei Emeltchenko wrote:
> From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
>
> Check uuid and connect to specified channel number directly.
> ---
> android/socket.c | 32 +++++++++++++++++++++++---------
> 1 file changed, 23 insertions(+), 9 deletions(-)
Please fix the commit message: capital UUID, s/is/if/ and
s/chan/channel/ in the subject.
> +static bool is_empty(const uint8_t *uuid)
> +{
> + static uint8_t zero_uuid[16];
> +
> + return memcmp(uuid, zero_uuid, sizeof(zero_uuid)) == 0;
> +}
> +
> static void handle_connect(const void *buf, uint16_t len)
> {
> const struct hal_cmd_sock_connect *cmd = buf;
> - struct rfcomm_sock *rfsock;
> + struct rfcomm_sock *rfsock = NULL;
Firstly this rfsock = NULL seems completely unrelated to this patch, and
secondly it's not even needed. Please remove it.
> uuid_t uuid;
> int hal_fd = -1;
>
> @@ -940,17 +947,21 @@ static void handle_connect(const void *buf, uint16_t len)
>
> android2bdaddr(cmd->bdaddr, &rfsock->dst);
>
> - memset(&uuid, 0, sizeof(uuid));
> - uuid.type = SDP_UUID128;
> - memcpy(&uuid.value.uuid128, cmd->uuid, sizeof(uint128_t));
> + if (is_empty(cmd->uuid)) {
> + if (!do_connect(rfsock, cmd->channel))
> + goto failed;
If this is_empty function was really needed it should at least be called
uuid_is_empty to make it clear what it's for. However, since it's a
one-line function and you've only got a single place needing it, I'd
just declare a static const uint8_t zero_uuuid[16] in handle_connect()
and do the memcmp directly there.
Johan
^ permalink raw reply
* [PATCH] android/pts: Add PICS, PIXITs and PTS for L2CAP
From: Sebastian Chlad @ 2013-12-18 19:32 UTC (permalink / raw)
To: johan.hedberg; +Cc: linux-bluetooth, Sebastian Chlad
In-Reply-To: <2115852EF878384FA984E6B76A9F379E164297@IRSMSX104.ger.corp.intel.com>
This allows better tracking of the current state of implementation
---
android/pics-l2cap.txt | 157 ++++++++++++++++++++++++++
android/pixit-l2cap.txt | 39 +++++++
android/pts-l2cap.txt | 293 ++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 489 insertions(+)
create mode 100644 android/pics-l2cap.txt
create mode 100644 android/pixit-l2cap.txt
create mode 100644 android/pts-l2cap.txt
diff --git a/android/pics-l2cap.txt b/android/pics-l2cap.txt
new file mode 100644
index 0000000..ef25133
--- /dev/null
+++ b/android/pics-l2cap.txt
@@ -0,0 +1,157 @@
+L2CAP PICS for the PTS tool.
+
+* - different than PTS defaults
+# - not yet implemented/supported
+
+M - mandatory
+O - optional
+
+ Roles
+-------------------------------------------------------------------------------
+Parameter Name Selected Description
+-------------------------------------------------------------------------------
+TSPC_L2CAP_1_1 True Data Channel Initiator (C.1)
+TSPC_L2CAP_1_2 True Data Channel Acceptor (C.1)
+TSPC_L2CAP_1_3 True (#) LE Master (C.2)
+TSPC_L2CAP_1_4 True (#) LE Slave (C.2)
+-------------------------------------------------------------------------------
+C.1: Mandatory IF BR/EDR or BR/EDR/LE is claimed, ELSE Excluded.
+C.2: Mandatory to support (at least one of TSPC_L2CAP_1_3 or TSPC_L2CAP_1_4)
+ IF LE or BR/EDR/LE claimed, ELSE Excluded.
+-------------------------------------------------------------------------------
+
+
+ General Operation
+-------------------------------------------------------------------------------
+Parameter Name Selected Description
+-------------------------------------------------------------------------------
+TSPC_L2CAP_2_1 True Support of L2CAP signaling channel (C.20)
+TSPC_L2CAP_2_2 True Support of configuration process (C.20)
+TSPC_L2CAP_2_4 True Support of command echo request (C.21)
+TSPC_L2CAP_2_3 True Support of connection oriented data
+ channel (C.20)
+TSPC_L2CAP_2_5 True Support of command echo response (C.20)
+TSPC_L2CAP_2_6 True (*) Support of command information request (C.21)
+TSPC_L2CAP_2_7 True Support of command information response (C.20)
+TSPC_L2CAP_2_8 False Support of a channel group (C.21)
+TSPC_L2CAP_2_9 False Support of packet for connectionless
+ channel (C.21)
+TSPC_L2CAP_2_10 False Support retransmission mode (C.21)
+TSPC_L2CAP_2_11 False Support flow control mode(C.21)
+TSPC_L2CAP_2_12 True (*) Enhanced Retransmission Mode (C.1, C.13)
+TSPC_L2CAP_2_13 True (*) Streaming Mode (C.1, C.14)
+TSPC_L2CAP_2_14 True (*) FCS Option (C.2)
+TSPC_L2CAP_2_15 True (*) Generate Local Busy Condition (C.3)
+TSPC_L2CAP_2_16 True (*) Send Reject (C.3)
+TSPC_L2CAP_2_17 True (*) Send Selective Reject (C.3)
+TSPC_L2CAP_2_18 True (*) Mandatory use of ERTM (C.4)
+TSPC_L2CAP_2_19 True (*) Mandatory use of Streaming Mode (C.5)
+TSPC_L2CAP_2_20 True (*) Optional use of ERTM (C.4)
+TSPC_L2CAP_2_21 True (*) Optional use of Streaming Mode (C.5)
+TSPC_L2CAP_2_22 True (*) Send data using SAR in ERTM (C.6)
+TSPC_L2CAP_2_23 True (*) Send data using SAR in Streaming Mode (C.7)
+TSPC_L2CAP_2_24 True (*) Actively request Basic Mode for a PSM that
+ supports the use of ERTM or Streaming
+ Mode (C.8)
+TSPC_L2CAP_2_25 True (*) Supports performing L2CAP channel mode
+ configuration fallback from SM
+ to ERTM (C.9)
+TSPC_L2CAP_2_26 True (*) Supports sending more than one unacknowledged
+ I-Frame when operating in ERTM (C.10)
+TSPC_L2CAP_2_27 True (*) Supports sending more than three unacknowledged
+ I-Frame when operating in ERTM (C.10)
+TSPC_L2CAP_2_28 True (*) Supports configuring the peer TxWindow
+ greater than 1 (C.11)
+TSPC_L2CAP_2_29 False AMP Support (C.12)
+TSPC_L2CAP_2_30 True (*) Fixed Channel Support (C.12)
+TSPC_L2CAP_2_31 False AMP Manager Support (C.12)
+TSPC_L2CAP_2_32 False ERTM over AMP (C.12)
+TSPC_L2CAP_2_33 False Streaming Mode Source over AMP Support (C.15)
+TSPC_L2CAP_2_34 False Streaming Mode Sink over AMP Support (C.15)
+TSPC_L2CAP_2_35 False Unicast Connectionless Data, Reception (C.1, C.16)
+TSPC_L2CAP_2_36 False Ability to transmit an unencrypted packet over
+ a Unicast connectionless L2CAP
+ channel (C.16)
+TSPC_L2CAP_2_37 False Ability to transmit an encrypted packet over
+ a Unicast connectionless L2CAP
+ channel (C.16)
+TSPC_L2CAP_2_38 False Extended Flow Specification for BR/EDR (C.8)
+TSPC_L2CAP_2_39 False Extended Window Size (C.8)
+TSPC_L2CAP_2_40 True (*) Support of Low Energy signaling channel (C.17)
+TSPC_L2CAP_2_41 True (*) Support of command reject (C.17)
+TSPC_L2CAP_2_42 True (*) Send Connection Parameter Update Request (C.18)
+TSPC_L2CAP_2_43 True (*) Send Connection Parameter Update Response (C.19)
+TSPC_L2CAP_2_44 False Extended Flow Specification for AMP (C.22)
+TSPC_L2CAP_2_45 False Send disconnect request command (O)
+-------------------------------------------------------------------------------
+C.1: Mandatory to support at least one of TSPC_L2CAP_2_12 OR TSPC_L2CAP_2_13 OR
+ TSPC_L2CAP_2_35 IF BR/EDR BR/EDR/LE AND SUM_ICS 31/7 (CSA1) OR
+ SUM_ICS 31/8 (3.0) OR SUM_ICS 31/9 (3.0+HS) OR SUM_ICS 31/10 (4.0))
+ is supported, ELSE Excluded
+C.2: Optional IF TSPC_L2CAP_2_12 OR TSPC_L2CAP_2_13 is claimed, ELSE Excluded.
+C.3: Optional IF TSPC_L2CAP_2_12 AND TSPC_L2CAP_2_28 is claimed, ELSE Excluded.
+C.4: IF TSPC_L2CAP_2_12 is claimed THEN either TSPC_L2CAP_2_18
+ OR TSPC_L2CAP_2_20 are Mandatory, ELSE Excluded.
+C.5: IF TSPC_L2CAP_2_13 is claimed THEN either TSPC_L2CAP_2_19
+ OR TSPC_L2CAP_2_21 are Mandatory, ELSE Excluded.
+C.6: Optional IF TSPC_L2CAP_2_12 is claimed, ELSE Excluded.
+C.7: Optional IF TSPC_L2CAP_2_13 is claimed, ELSE Excluded.
+C.8: Optional IF TSPC_L2CAP_2_12 OR TSPC_L2CAP_2_13 is claimed, ELSE Excluded.
+C.9: Mandatory IF TSPC_L2CAP_2_12 AND TSPC_L2CAP_2_13 AND TSPC_L2CAP_2_21
+ is claimed, ELSE Excluded.
+C.10: Optional IF TSPC_L2CAP_2_12 is claimed, ELSE Excluded.
+C.11: Optional IF TSPC_L2CAP_2_12 is claimed, ELSE Excluded.
+C.12: Mandatory IF SUM_ICS 31/9 (3.0 + HS) is claimed, ELSE Optional.
+C.13: Mandatory IF SUM_ICS 31/9 (3.0 + HS) is claimed, ELSE Optional.
+C.14: Optional IF SUM_ICS 31/8 OR 31/9 OR 31/10 OR 31/11 is claimed, ELSE Excluded.
+C.15: Optional IF TSPC_L2CAP_2_29 is claimed, ELSE Excluded.
+C.16: Optional IF (SUM_ICS 31/8 OR SUM_ICS 31/9 OR 31/10 OR 31/11) is claimed,
+ ELSE Excluded.
+C.17: Mandatory IF LE OR BR/EDR/LE is claimed, ELSE Excluded.
+C.18: Optional IF (SUM_ICS 31/10 AND 1/4) is claimed, ELSE Excluded.
+C.19: Mandatory IF (SUM_ICS 31/10 AND 1/3) is claimed, ELSE Excluded.
+C.20: Mandatory IF LE OR BR/EDR/LE, is claimed, ELSE Excluded
+C.21: Optional IF LE OR BR/EDR/LE, is claimed, ELSE Excluded
+C.22: Mandatory IF TSPC_L2CAP_2_29 is claimed, ELSE Excluded.
+-------------------------------------------------------------------------------
+
+
+ Configurable Parameters
+-------------------------------------------------------------------------------
+Parameter Name Selected Description
+-------------------------------------------------------------------------------
+TSPC_L2CAP_3_1 True Support of RTX timer (M)
+TSPC_L2CAP_3_2 True Support of ERTX timer (C.4)
+TSPC_L2CAP_3_3 True Support minimum MTU size 48 octets (C.4)
+TSPC_L2CAP_3_4 True (*) Support MTU size larger than 48 octets (C.5)
+TSPC_L2CAP_3_5 True Support of flush timeout value for reliable
+ channel (C.4)
+TSPC_L2CAP_3_6 False Support of flush timeout value for unreliable
+ channel (C.5)
+TSPC_L2CAP_3_7 False Support of bi-directional quality of service
+ (QoS) option field (C.1)
+TSPC_L2CAP_3_8 False Negotiate QoS service type (C.5)
+TSPC_L2CAP_3_9 False Negotiate and support service type ‘No
+ traffic’ (C.2)
+TSPC_L2CAP_3_10 False Negotiate and support service type ‘Best
+ effort’ (C.3)
+TSPC_L2CAP_3_11 False Negotiate and support service type
+ ‘Guaranteed’ (C.2)
+TSPC_L2CAP_3_12 True (*) Support minimum MTU size 23 octets (C.6)
+TSPC_L2CAP_3_13 False Negotiate and support service type ‘No traffic’
+ for Extended Flow Specification (C.7)
+TSPC_L2CAP_3_14 False Negotiate and support service type ‘Best Effort'
+ for Extended Flow Specification (C.8)
+TSPC_L2CAP_3_15 False Negotiate and support service type ‘Guaranteed’
+ for Extended Flow Specification (C.9)
+-------------------------------------------------------------------------------
+C.1: Mandatory if TSPC_L2CAP_3_8 is supported, ELSE Optional.
+C.2: Optional if TSPC_L2CAP_3_8 is supported, ELSE Excluded.
+C.3: Mandatory if TSPC_L2CAP_3_8 is supported, ELSE Excluded.
+C.4: Mandatory IF BR/EDR OR BR/EDR/LE is claimed, ELSE Excluded.
+C.5: Optional IF BR/EDR OR BR/EDR/LE is claimed, ELSE Excluded.
+C.6: Mandatory IF LE OR BR/EDR/LE is claimed, ELSE Excluded.
+C.7: Optional if TSPC_L2CAP_2_44 OR TSPC_L2CAP_2_38 is supported, ELSE Excluded.
+C.8: Mandatory if TSPC_L2CAP_2_44 OR TSPC_L2CAP_2_38 is supported, ELSE Excluded.
+C.9: Optional if TSPC_L2CAP_2_44 OR TSPC_L2CAP_2_38 is supported, ELSE Excluded.
+-------------------------------------------------------------------------------
diff --git a/android/pixit-l2cap.txt b/android/pixit-l2cap.txt
new file mode 100644
index 0000000..7de6638
--- /dev/null
+++ b/android/pixit-l2cap.txt
@@ -0,0 +1,39 @@
+L2CAP PIXIT for the PTS tool.
+
+* - different than PTS defaults
+& - should be set to IUT Bluetooth address
+
+ Required PIXIT settings
+-------------------------------------------------------------------------------
+Parameter Name Value
+-------------------------------------------------------------------------------
+TSPX_bd_addr_iut 112233445566 (*&)
+TSPX_client_class_of_device 100104
+TSPX_server_class_of_device 100104
+TSPX_security_enabled FALSE
+TSPX_delete_link_key FALSE
+TSPX_pin_code 0000
+TSPX_flushto FFFF
+TSPX_inmtu 02A0
+TSPX_no_fail_verditcs FALSE
+TSPX_oumtu 02A0
+TSPX_iut_role_initiator FALSE
+TSPX_psm 1011 (*)
+TSPX_time_guard 180000
+TSPX_timer_ertx 120000
+TSPX_timer_ertx_max 300000
+TSPX_timer_ertx_min 60000
+TSPX_timer_rtx 10000
+TSPX_timer_rtx_max 60000
+TSPX_timer_rtx_min 1000
+TSPX_rfc_mode_tx_window_size 08
+TSPX_rfc_mode_max_transmit 03
+TSPX_rfc_mode_retransmission_timeout 07D0
+TSPX_rfc_mode_monitor_timeout 2EE0
+TSPX_rfc_mode_maximum_pdu_size 02A0
+TSPX_extended_window_size 0012
+TSPX_use_implicit_send TRUE
+TSPX_use_dynamic_pin FALSE
+TSPX_iut_SDU_size_in_bytes 144
+TSPX_secure_simple_pairing_pass_key_confirmation FALSE
+-------------------------------------------------------------------------------
diff --git a/android/pts-l2cap.txt b/android/pts-l2cap.txt
new file mode 100644
index 0000000..66dc36b
--- /dev/null
+++ b/android/pts-l2cap.txt
@@ -0,0 +1,293 @@
+PTS test results for L2CAP
+
+PTS version: 5.0
+Tested: 18.12.2013
+
+Results:
+PASS test passed
+FAIL test failed
+INC test is inconclusive
+N/A test is disabled due to PICS setup
+
+-------------------------------------------------------------------------------
+Test Name Result Notes
+-------------------------------------------------------------------------------
+TC_COS_CED_BV_01_C PASS
+TC_COS_CED_BV_03_C PASS
+TC_COS_CED_BV_04_C N/A
+TC_COS_CED_BV_05_C PASS
+TC_COS_CED_BV_07_C PASS
+TC_COS_CED_BV_08_C PASS
+TC_COS_CED_BV_09_C INC
+TC_COS_CED_BV_10_C N/A
+TC_COS_CED_BV_11_C PASS
+TC_COS_CED_BI_01_C PASS
+TC_COS_CFD_BV_01_C PASS
+TC_COS_CFD_BV_02_C PASS
+TC_COS_CFD_BV_03_C PASS
+TC_COS_CFD_BV_08_C INC
+TC_COS_CFD_BV_09_C INC
+TC_COS_CFD_BV_10_C N/A
+TC_COS_CFD_BI_11_C PASS
+TC_COS_CFD_BV_12_C PASS
+TC_COS_CFD_BV_13_C N/A
+TC_COS_IEX_BV_01_C PASS
+TC_COS_IEX_BV_02_C PASS
+TC_COS_ECH_BV_01_C PASS
+TC_COS_ECH_BV_02_C INC
+TC_CLS_CLR_BV_01_C N/A
+TC_CLS_UCD_BV_01_C N/A
+TC_CLS_UCD_BV_02_C N/A
+TC_CLS_UCD_BV_03_C N/A
+TC_EXF_BV_01_C PASS
+TC_EXF_BV_02_C PASS
+TC_EXF_BV_03_C PASS
+TC_EXF_BV_04_C N/A
+TC_EXF_BV_05_C PASS
+TC_EXF_BV_06_C N/A
+TC_CMC_BV_01_C INC
+TC_CMC_BV_02_C INC
+TC_CMC_BV_03_C INC
+TC_CMC_BV_04_C INC
+TC_CMC_BV_05_C INC
+TC_CMC_BV_06_C INC
+TC_CMC_BV_07_C INC
+TC_CMC_BV_08_C INC
+TC_CMC_BV_09_C INC
+TC_CMC_BV_10_C INC
+TC_CMC_BV_11_C INC
+TC_CMC_BV_12_C INC
+TC_CMC_BV_13_C INC
+TC_CMC_BV_14_C INC
+TC_CMC_BV_15_C INC
+TC_CMC_BI_01_C INC
+TC_CMC_BI_02_C INC
+TC_CMC_BI_03_C INC
+TC_CMC_BI_04_C INC
+TC_CMC_BI_05_C INC
+TC_CMC_BI_06_C INC
+TC_FOC_BV_01_C INC
+TC_FOC_BV_02_C INC
+TC_FOC_BV_03_C INC
+TC_FOC_BV_04_C INC
+TC_OFS_BV_01_C INC
+TC_OFS_BV_02_C INC
+TC_OFS_BV_03_C INC
+TC_OFS_BV_04_C INC
+TC_OFS_BV_05_C INC
+TC_OFS_BV_06_C INC
+TC_OFS_BV_07_C INC
+TC_OFS_BV_08_C INC
+TC_ERM_BV_01_C INC
+TC_ERM_BV_02_C INC
+TC_ERM_BV_03_C INC
+TC_ERM_BV_04_C INC
+TC_ERM_BV_05_C INC
+TC_ERM_BV_06_C INC
+TC_ERM_BV_07_C INC
+TC_ERM_BV_08_C INC
+TC_ERM_BV_09_C INC
+TC_ERM_BV_10_C INC
+TC_ERM_BV_11_C INC
+TC_ERM_BV_12_C INC
+TC_ERM_BV_13_C INC
+TC_ERM_BV_14_C INC
+TC_ERM_BV_15_C INC
+TC_ERM_BV_16_C INC
+TC_ERM_BV_17_C INC
+TC_ERM_BV_18_C INC
+TC_ERM_BV_19_C INC
+TC_ERM_BV_20_C INC
+TC_ERM_BV_21_C INC
+TC_ERM_BV_22_C INC
+TC_ERM_BV_23_C INC
+TC_ERM_BI_01_C INC
+TC_ERM_BI_02_C INC
+TC_ERM_BI_03_C INC
+TC_ERM_BI_04_C INC
+TC_ERM_BI_05_C INC
+TC_STM_BV_01_C INC
+TC_STM_BV_02_C INC
+TC_STM_BV_03_C INC
+TC_STM_BV_11_C N/A
+TC_STM_BV_12_C N/A
+TC_STM_BV_13_C N/A
+TC_FIX_BV_01_C PASS
+TC_FIX_BV_02_C PASS
+TC_EWC_BV_01_C N/A
+TC_EWC_BV_02_C N/A
+TC_EWC_BV_03_C N/A
+TC_LSC_BV_01_C N/A
+TC_LSC_BV_02_C N/A
+TC_LSC_BV_03_C N/A
+TC_LSC_BI_04_C N/A
+TC_LSC_BI_05_C N/A
+TC_LSC_BV_06_C N/A
+TC_LSC_BV_07_C N/A
+TC_LSC_BV_08_C N/A
+TC_LSC_BV_09_C N/A
+TC_LSC_BI_10_C N/A
+TC_LSC_BI_11_C N/A
+TC_LSC_BV_12_C N/A
+TC_CCH_BV_01_C N/A
+TC_CCH_BV_02_C N/A
+TC_CCH_BV_03_C N/A
+TC_CCH_BV_04_C N/A
+TC_ECF_BV_01_C N/A
+TC_ECF_BV_02_C N/A
+TC_ECF_BV_03_C N/A
+TC_ECF_BV_04_C N/A
+TC_ECF_BV_05_C N/A
+TC_ECF_BV_06_C N/A
+TC_ECF_BV_07_C N/A
+TC_ECF_BV_08_C N/A
+TC_LE_CPU_BV_01_C N/A
+TC_LE_CPU_BV_02_C N/A
+TC_LE_CPU_BI_01_C N/A
+TC_LE_CPU_BI_02_C N/A
+TC_LE_REJ_BV_01_C N/A
+
+-------------------------------------------------------------------------------
+ HELPER SECTION
+-------------------------------------------------------------------------------
+Test Name Result Notes
+-------------------------------------------------------------------------------
+TC_HELPER_COS_CED_BV_01_C PASS
+TC_HELPER_COS_CED_BV_03_C PASS
+TC_HELPER_COS_CED_BV_04_C N/A
+TC_HELPER_COS_CED_BV_05_C PASS
+TC_HELPER_COS_CED_BV_07_C N/A
+TC_HELPER_COS_CED_BV_08_C PASS
+TC_HELPER_COS_CED_BV_09_C PASS
+TC_HELPER_COS_CED_BV_11_C PASS
+TC_HELPER_COS_CED_BI_01_C PASS
+TC_HELPER_COS_CFD_BV_01_C INC
+TC_HELPER_COS_CFD_BV_02_C INC
+TC_HELPER_COS_CFD_BV_03_C INC
+TC_HELPER_COS_CFD_BV_08_C PASS
+TC_HELPER_COS_CFD_BV_09_C PASS
+TC_HELPER_COS_CFD_BV_10_C INC
+TC_HELPER_COS_CFD_BV_11_C INC
+TC_HELPER_COS_CFD_BV_12_C PASS
+TC_HELPER_COS_CFD_BV_13_C INC
+TC_HELPER_CLS_CLR_BV_01_C PASS
+TC_HELPER_CLS_UCD_BV_01_C N/A
+TC_HELPER_CLS_UCD_BV_02_C N/A
+TC_HELPER_CLS_UCD_BV_03_C N/A
+TC_HELPER_EXF_BV_01_C PASS
+TC_HELPER_EXF_BV_02_C PASS
+TC_HELPER_EXF_BV_03_C PASS
+TC_HELPER_EXF_BV_04_C PASS
+TC_HELPER_EXF_BV_05_C PASS
+TC_HELPER_EXF_BV_06_C PASS
+TC_HELPER_CMC_BV_01_C INC
+TC_HELPER_CMC_BV_02_C INC
+TC_HELPER_CMC_BV_03_C INC
+TC_HELPER_CMC_BV_405_C INC
+TC_HELPER_CMC_BV_06_C INC
+TC_HELPER_CMC_BV_07_C INC
+TC_HELPER_CMC_BV_08_C INC
+TC_HELPER_CMC_BV_09_C INC
+TC_HELPER_CMC_BV_10_C INC
+TC_HELPER_CMC_BV_11_C INC
+TC_HELPER_CMC_BV_12_C INC
+TC_HELPER_CMC_BV_13_C INC
+TC_HELPER_CMC_BV_14_C INC
+TC_HELPER_CMC_BV_15_C INC
+TC_HELPER_CMC_BI_01_C INC
+TC_HELPER_CMC_BI_02_C INC
+TC_HELPER_CMC_BI_03_C INC
+TC_HELPER_CMC_BI_04_C INC
+TC_HELPER_CMC_BI_05_C INC
+TC_HELPER_CMC_BI_06_C INC
+TC_HELPER_FOC_BV_01_ALT_1_C INC
+TC_HELPER_FOC_BV_01_ALT_2_C INC
+TC_HELPER_FOC_BV_02_ALT_1_C INC
+TC_HELPER_FOC_BV_02_ALT_2_C INC
+TC_HELPER_FOC_BV_03_ALT_1_C INC
+TC_HELPER_FOC_BV_03_ALT_2_C INC
+TC_HELPER_FOC_BV_04_ALT_1_C INC
+TC_HELPER_FOC_BV_04_ALT_2_C INC
+TC_HELPER_OFS_BV_01_C INC
+TC_HELPER_OFS_BV_02_C INC
+TC_HELPER_OFS_BV_03_C INC
+TC_HELPER_OFS_BV_04_C INC
+TC_HELPER_OFS_BV_05_C INC
+TC_HELPER_OFS_BV_06_C INC
+TC_HELPER_OFS_BV_07_C INC
+TC_HELPER_OFS_BV_08_C INC
+TC_HELPER_ERM_BV_01_C INC
+TC_HELPER_ERM_BV_02_C INC
+TC_HELPER_ERM_BV_02_C__no_Sframe_C INC
+TC_HELPER_ERM_BV_03_C INC
+TC_HELPER_ERM_BV_05_C INC
+TC_HELPER_ERM_BV_06_C INC
+TC_HELPER_ERM_BV_07_C_ALT_1_C INC
+TC_HELPER_ERM_BV_07_C_ALT_2_C INC
+TC_HELPER_ERM_BV_08_C INC
+TC_HELPER_ERM_BV_09_C INC
+TC_HELPER_ERM_BV_10_C INC
+TC_HELPER_ERM_BV_11_C INC
+TC_HELPER_ERM_BV_12_C INC
+TC_HELPER_ERM_BV_13_C INC
+TC_HELPER_ERM_BV_14_C INC
+TC_HELPER_ERM_BV_15_C INC
+TC_HELPER_ERM_BV_16_C INC
+TC_HELPER_ERM_BV_17_C INC
+TC_HELPER_ERM_BV_18_C INC
+TC_HELPER_ERM_BV_19_C INC
+TC_HELPER_ERM_BV_20_C INC
+TC_HELPER_ERM_BV_21_C INC
+TC_HELPER_ERM_BV_21_TxWin1_C INC
+TC_HELPER_ERM_BV_21_ALT_1_C INC
+TC_HELPER_ERM_BV_21_ALT_2_C INC
+TC_HELPER_ERM_BV_22_ALT_1_C INC
+TC_HELPER_ERM_BV_22_ALT_2_C INC
+TC_HELPER_ERM_BV_23_C INC
+TC_HELPER_ERM_BI_1_C INC
+TC_HELPER_ERM_BI_2_C INC
+TC_HELPER_ERM_BI_3_C INC
+TC_HELPER_ERM_BI_4_C INC
+TC_HELPER_ERM_BI_5_ALT_1_C INC
+TC_HELPER_ERM_BI_5_ALT_2_C INC
+TC_HELPER_ERM_BI_5_ALT_3_C INC
+TC_HELPER_STM_BV_01_C INC
+TC_HELPER_STM_BV_02_C INC
+TC_HELPER_STM_BV_03_C INC
+TC_HELPER_STM_BV_11_C N/A
+TC_HELPER_STM_BV_12_C N/A
+TC_HELPER_STM_BV_13_C N/A
+TC_HELPER_FIX_BV_01_C PASS
+TC_HELPER_FIX_BV_02_C PASS
+TC_HELPER_EWC_BV_01_C INC
+TC_HELPER_EWC_BV_02_C INC
+TC_HELPER_EWC_BV_03_C INC
+TC_HELPER_LSC_BV_01_C N/A
+TC_HELPER_LSC_BV_02_C N/A
+TC_HELPER_LSC_BV_03_C N/A
+TC_HELPER_LSC_BI_04_C N/A
+TC_HELPER_LSC_BI_05_C N/A
+TC_HELPER_LSC_BV_06_C N/A
+TC_HELPER_LSC_BV_07_C N/A
+TC_HELPER_LSC_BV_08_C N/A
+TC_HELPER_LSC_BV_09_C N/A
+TC_HELPER_LSC_BI_10_C N/A
+TC_HELPER_LSC_BI_11_C N/A
+TC_HELPER_LSC_BV_12_C N/A
+TC_HELPER_CCH_BV_01_C N/A
+TC_HELPER_CCH_BV_02_C N/A
+TC_HELPER_CCH_BV_03_C N/A
+TC_HELPER_CCH_BV_04_C N/A
+TC_HELPER_ECF_BV_01_C N/A
+TC_HELPER_ECF_BV_02_C N/A
+TC_HELPER_ECF_BV_03_C N/A
+TC_HELPER_ECF_BV_04_C N/A
+TC_HELPER_ECF_BV_05_C N/A
+TC_HELPER_ECF_BV_06_C N/A
+TC_HELPER_ECF_BV_07_C N/A
+TC_HELPER_ECF_BV_08_C N/A
+TC_HELPER_LE_CPU_BV_01_C N/A
+TC_HELPER_LE_CPU_BV_02_C N/A
+TC_HELPER_LE_CPU_BI_01_C N/A
+TC_HELPER_LE_CPU_BI_02_C N/A
+TC_HELPER_LE_REJ_BI_01_C N/A
--
1.8.1.2
^ permalink raw reply related
* Re: pull request: bluetooth 2013-12-18
From: John W. Linville @ 2013-12-18 19:23 UTC (permalink / raw)
To: Gustavo Padovan, linux-wireless, linux-bluetooth, linux-kernel
In-Reply-To: <20131218125236.GA1376@joana>
On Wed, Dec 18, 2013 at 10:52:36AM -0200, Gustavo Padovan wrote:
> Hi John,
>
> Two patches in this pull request. An important fix from Marcel in the
> permission check for HCI User Channels, there was a extra check for
> CAP_NET_RAW, and it was now removed. These channels should only require
> CAP_NET_ADMIN. The other patch is a device id addition.
>
> Please pull or let me know of any problems! Thanks.
>
> Gustavo
>
> ---
> The following changes since commit eafbdde9c5629bea58df07275c5917eb42afbbe7:
>
> rtlwifi: rtl8192cu: Fix more pointer arithmetic errors (2013-11-15 14:29:33 -0500)
>
> are available in the git repository at:
>
> git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth.git for-upstream
>
> for you to fetch changes up to 1bc5ad168f441f6f8bfd944288a5f7b4963ac1f6:
>
> Bluetooth: Fix HCI User Channel permission check in hci_sock_sendmsg (2013-12-17 13:47:27 +0200)
Pulling now...
--
John W. Linville Someday the world will need a hero, and you
linville@tuxdriver.com might be all we have. Be ready.
^ permalink raw reply
* [PATCH 2/2] android/socket: Handle Android events for server socket
From: Andrei Emeltchenko @ 2013-12-18 15:15 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1387379717-1457-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Add watch for tracking events from Android framework for server socket.
Android might want to close server connection, in this case we close
our listening socket and cleaning up rfsock structure. Glib watch is
added with high priority to avoid races.
---
android/socket.c | 32 +++++++++++++++++++++++++++++++-
1 file changed, 31 insertions(+), 1 deletion(-)
diff --git a/android/socket.c b/android/socket.c
index 7bc5b0b..de98ae4 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -622,6 +622,24 @@ static bool sock_send_accept(struct rfcomm_sock *rfsock, bdaddr_t *bdaddr,
return true;
}
+static gboolean sock_server_stack_event_cb(GIOChannel *io, GIOCondition cond,
+ gpointer data)
+{
+ struct rfcomm_sock *rfsock = data;
+
+ DBG("sock %d cond %d", g_io_channel_unix_get_fd(io), cond);
+
+ if (cond & G_IO_NVAL)
+ return FALSE;
+
+ if (cond & (G_IO_ERR | G_IO_HUP )) {
+ servers = g_list_remove(servers, rfsock);
+ cleanup_rfsock(rfsock);
+ }
+
+ return FALSE;
+}
+
static void accept_cb(GIOChannel *io, GError *err, gpointer user_data)
{
struct rfcomm_sock *rfsock = user_data;
@@ -697,10 +715,12 @@ static void handle_listen(const void *buf, uint16_t len)
const struct profile_info *profile;
struct rfcomm_sock *rfsock = NULL;
BtIOSecLevel sec_level;
- GIOChannel *io;
+ GIOChannel *io, *io_stack;
+ GIOCondition cond;
GError *err = NULL;
int hal_fd = -1;
int chan;
+ guint id;
DBG("");
@@ -738,6 +758,16 @@ static void handle_listen(const void *buf, uint16_t len)
g_io_channel_set_close_on_unref(io, FALSE);
g_io_channel_unref(io);
+ /* Handle events from Android */
+ cond = G_IO_HUP | G_IO_ERR | G_IO_NVAL;
+ io_stack = g_io_channel_unix_new(rfsock->fd);
+ id = g_io_add_watch_full(io_stack, G_PRIORITY_HIGH, cond,
+ sock_server_stack_event_cb, rfsock,
+ NULL);
+ g_io_channel_unref(io_stack);
+
+ rfsock->stack_watch = id;
+
DBG("real_sock %d fd %d hal_fd %d", rfsock->real_sock, rfsock->fd,
hal_fd);
--
1.8.3.2
^ permalink raw reply related
* [PATCH 1/2] android/tester: Add Socket test close and listen
From: Andrei Emeltchenko @ 2013-12-18 15:15 UTC (permalink / raw)
To: linux-bluetooth
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
This test the situation when Android close file descriptor we passed to
it and try to listen() again.
---
android/android-tester.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 55 insertions(+)
diff --git a/android/android-tester.c b/android/android-tester.c
index 8a2861e..cb8fb4e 100644
--- a/android/android-tester.c
+++ b/android/android-tester.c
@@ -1141,6 +1141,57 @@ clean:
close(sock_fd);
}
+static void test_listen_close(const void *test_data)
+{
+ struct test_data *data = tester_get_data();
+ const struct socket_data *test = data->test_data;
+ bt_status_t status;
+ int sock_fd = -1;
+
+ status = data->if_sock->listen(test->sock_type,
+ test->service_name, test->service_uuid,
+ test->channel, &sock_fd, test->flags);
+ if (status != test->expected_status) {
+ tester_test_failed();
+ goto clean;
+ }
+
+ /* Check that file descriptor is valid */
+ if (status == BT_STATUS_SUCCESS && fcntl(sock_fd, F_GETFD) == -1) {
+ tester_test_failed();
+ return;
+ }
+
+ tester_print("sock_fd: %d", sock_fd);
+
+ /* Now close sock_fd */
+ close(sock_fd);
+
+ /* Try to listen again */
+ status = data->if_sock->listen(test->sock_type,
+ test->service_name, test->service_uuid,
+ test->channel, &sock_fd, test->flags);
+ if (status != test->expected_status) {
+ tester_test_failed();
+ goto clean;
+ }
+
+ /* Check that file descriptor is valid */
+ if (status == BT_STATUS_SUCCESS && fcntl(sock_fd, F_GETFD) == -1) {
+ tester_test_failed();
+ return;
+ }
+
+ tester_print("sock_fd: %d", sock_fd);
+
+ tester_test_passed();
+
+clean:
+ if (sock_fd >= 0)
+ close(sock_fd);
+
+}
+
static void test_generic_connect(const void *test_data)
{
struct test_data *data = tester_get_data();
@@ -1363,6 +1414,10 @@ int main(int argc, char *argv[])
&btsock_success_check_chan,
setup_socket_interface, test_generic_listen, teardown);
+ test_bredrle("Socket Listen - Close and Listen again",
+ &btsock_success_check_chan,
+ setup_socket_interface, test_listen_close, teardown);
+
test_bredrle("Socket Connect - Invalid: sock_type 0",
&btsock_inv_param_socktype, setup_socket_interface,
test_generic_connect, teardown);
--
1.8.3.2
^ permalink raw reply related
* [PATCH_v4 7/7] bnep: Refactored bnep server apis for bridge addition and deletion
From: Ravi kumar Veeramally @ 2013-12-18 14:53 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Ravi kumar Veeramally
In-Reply-To: <1387378396-6259-1-git-send-email-ravikumar.veeramally@linux.intel.com>
To simplify bnep server realted bridge creation and deletion calls
provided extra apis and moved existing apis to static.
---
profiles/network/bnep.c | 50 +++++++++++++++++++++++++++++++++++++++++------
profiles/network/bnep.h | 9 +++------
profiles/network/server.c | 37 +++--------------------------------
3 files changed, 50 insertions(+), 46 deletions(-)
diff --git a/profiles/network/bnep.c b/profiles/network/bnep.c
index b7c3835..90728d3 100644
--- a/profiles/network/bnep.c
+++ b/profiles/network/bnep.c
@@ -151,7 +151,7 @@ int bnep_cleanup(void)
return 0;
}
-int bnep_conndel(const bdaddr_t *dst)
+static int bnep_conndel(const bdaddr_t *dst)
{
struct bnep_conndel_req req;
@@ -167,7 +167,7 @@ int bnep_conndel(const bdaddr_t *dst)
return 0;
}
-int bnep_connadd(int sk, uint16_t role, char *dev)
+static int bnep_connadd(int sk, uint16_t role, char *dev)
{
struct bnep_connadd_req req;
@@ -187,7 +187,7 @@ int bnep_connadd(int sk, uint16_t role, char *dev)
return 0;
}
-int bnep_if_up(const char *devname)
+static int bnep_if_up(const char *devname)
{
struct ifreq ifr;
int sk, err;
@@ -212,7 +212,7 @@ int bnep_if_up(const char *devname)
return 0;
}
-int bnep_if_down(const char *devname)
+static int bnep_if_down(const char *devname)
{
struct ifreq ifr;
int sk, err;
@@ -455,7 +455,7 @@ guint bnep_set_watchdog(struct bnep *b, GIOFunc watchdog, void *data)
return ret;
}
-int bnep_add_to_bridge(const char *devname, const char *bridge)
+static int bnep_add_to_bridge(const char *devname, const char *bridge)
{
int ifindex;
struct ifreq ifr;
@@ -486,7 +486,7 @@ int bnep_add_to_bridge(const char *devname, const char *bridge)
return 0;
}
-int bnep_del_from_bridge(const char *devname, const char *bridge)
+static int bnep_del_from_bridge(const char *devname, const char *bridge)
{
int ifindex = if_nametoindex(devname);
struct ifreq ifr;
@@ -592,3 +592,41 @@ uint16_t bnep_setup_decode(struct bnep_setup_conn_req *req, uint16_t *dst,
return BNEP_SUCCESS;
}
+
+int bnep_server_add(int sk, uint16_t dst, char *bridge, char *iface,
+ const bdaddr_t *addr)
+{
+ if (!bridge || !bridge || !iface || !addr)
+ return -EINVAL;
+
+ if (bnep_connadd(sk, dst, iface) < 0) {
+ error("Can't add connection to the bridge %s: %s(%d)",
+ bridge, strerror(errno), errno);
+ return -errno;
+ }
+
+ if (bnep_add_to_bridge(iface, bridge) < 0) {
+ error("Can't add %s to the bridge %s: %s(%d)",
+ iface, bridge, strerror(errno), errno);
+ bnep_conndel(addr);
+ return -errno;
+ }
+
+ if (bnep_if_up(iface) < 0) {
+ error("Can't up the interface %s: %s(%d)",
+ iface, strerror(errno), errno);
+ return -errno;
+ }
+
+ return 0;
+}
+
+void bnep_server_delete(char *bridge, char *iface, const bdaddr_t *addr)
+{
+ if (!bridge || !iface || !addr)
+ return;
+
+ bnep_del_from_bridge(iface, bridge);
+ bnep_if_down(iface);
+ bnep_conndel(addr);
+}
diff --git a/profiles/network/bnep.h b/profiles/network/bnep.h
index 46199df..3447f6e 100644
--- a/profiles/network/bnep.h
+++ b/profiles/network/bnep.h
@@ -32,12 +32,6 @@ const char *bnep_name(uint16_t id);
struct bnep *bnep_new(int sk, uint16_t local_role, uint16_t remote_role);
void bnep_free(struct bnep *b);
-int bnep_connadd(int sk, uint16_t role, char *dev);
-int bnep_conndel(const bdaddr_t *dst);
-int bnep_if_up(const char *devname);
-int bnep_if_down(const char *devname);
-int bnep_add_to_bridge(const char *devname, const char *bridge);
-int bnep_del_from_bridge(const char *devname, const char *bridge);
typedef void (*bnep_connect_cb) (char *iface, int err, void *data);
int bnep_connect(struct bnep *b, bnep_connect_cb conn_cb, void *data);
@@ -48,3 +42,6 @@ ssize_t bnep_send_ctrl_rsp(int sk, uint8_t type, uint8_t ctrl, uint16_t resp);
uint16_t bnep_setup_chk(uint16_t dst_role, uint16_t src_role);
uint16_t bnep_setup_decode(struct bnep_setup_conn_req *req, uint16_t *dst,
uint16_t *src);
+int bnep_server_add(int sk, uint16_t dst, char *bridge, char *iface,
+ const bdaddr_t *addr);
+void bnep_server_delete(char *bridge, char *iface, const bdaddr_t *addr);
diff --git a/profiles/network/server.c b/profiles/network/server.c
index 73741ec..7cb5a1e 100644
--- a/profiles/network/server.c
+++ b/profiles/network/server.c
@@ -251,35 +251,6 @@ static sdp_record_t *server_record_new(const char *name, uint16_t id)
return record;
}
-static int server_connadd(struct network_server *ns,
- struct network_session *session,
- uint16_t dst_role)
-{
- char devname[16];
- int err, nsk;
-
- nsk = g_io_channel_unix_get_fd(session->io);
- err = bnep_connadd(nsk, dst_role, devname);
- if (err < 0)
- return err;
-
- info("Added new connection: %s", devname);
-
- if (bnep_add_to_bridge(devname, ns->bridge) < 0) {
- error("Can't add %s to the bridge %s: %s(%d)",
- devname, ns->bridge, strerror(errno), errno);
- return -EPERM;
- }
-
- bnep_if_up(devname);
-
- strncpy(session->dev, devname, sizeof(devname));
-
- ns->sessions = g_slist_append(ns->sessions, session);
-
- return 0;
-}
-
static void session_free(void *data)
{
struct network_session *session = data;
@@ -377,7 +348,8 @@ static gboolean bnep_setup(GIOChannel *chan,
goto reply;
}
- if (server_connadd(ns, na->setup, dst_role) < 0)
+ if (bnep_server_add(sk, dst_role, ns->bridge, na->setup->dev,
+ &na->setup->dst) < 0)
goto reply;
na->setup = NULL;
@@ -524,10 +496,7 @@ static void server_remove_sessions(struct network_server *ns)
if (*session->dev == '\0')
continue;
- bnep_del_from_bridge(session->dev, ns->bridge);
- bnep_if_down(session->dev);
-
- bnep_conndel(&session->dst);
+ bnep_server_delete(ns->bridge, session->dev, &session->dst);
}
g_slist_free_full(ns->sessions, session_free);
--
1.8.3.2
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox