All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCHv2 0/6] RFCOMM data transfer support in bthost
@ 2014-02-18  7:50 Marcin Kraglak
  2014-02-18  7:50 ` [PATCHv2 1/6] emulator/bthost: Add api to handle RFCOMM data on bthost Marcin Kraglak
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: Marcin Kraglak @ 2014-02-18  7:50 UTC (permalink / raw)
  To: linux-bluetooth

v2:
 - Added rfcomm prefixes in API functions and internal structs
 - Values returned by read() and write stored in local variables
for clarity
 - Few coding style fixes

Marcin Kraglak (6):
  emulator/bthost: Add api to handle RFCOMM data on bthost
  tools/rfcomm-tester: Add RFCOMM client write test case
  tools/rfcomm-tester: Add RFCOMM server write test case
  emulator/bthost: Add function to send RFCOMM UIH frames from bthost
  tools/rfcomm-tester: Add RFCOMM client read test case
  tools/rfcomm-tester: Add RFCOMM server read test case

 emulator/bthost.c     | 167 ++++++++++++++++++++++++++++++++++++++-
 emulator/bthost.h     |  13 ++++
 tools/rfcomm-tester.c | 212 +++++++++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 387 insertions(+), 5 deletions(-)

-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCHv2 1/6] emulator/bthost: Add api to handle RFCOMM data on bthost
  2014-02-18  7:50 [PATCHv2 0/6] RFCOMM data transfer support in bthost Marcin Kraglak
@ 2014-02-18  7:50 ` Marcin Kraglak
  2014-02-18  7:50 ` [PATCHv2 2/6] tools/rfcomm-tester: Add RFCOMM client write test case Marcin Kraglak
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Marcin Kraglak @ 2014-02-18  7:50 UTC (permalink / raw)
  To: linux-bluetooth

With this change user can handle data received on RFCOMM connection.
---
 emulator/bthost.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++----
 emulator/bthost.h |  9 +++++++
 2 files changed, 75 insertions(+), 4 deletions(-)

diff --git a/emulator/bthost.c b/emulator/bthost.c
index 6fbabe8..9bf9ad3 100644
--- a/emulator/bthost.c
+++ b/emulator/bthost.c
@@ -126,6 +126,13 @@ struct cid_hook {
 	struct cid_hook *next;
 };
 
+struct rfcomm_channel_hook {
+	uint8_t channel;
+	bthost_rfcomm_channel_hook_func_t func;
+	void *user_data;
+	struct rfcomm_channel_hook *next;
+};
+
 struct btconn {
 	uint16_t handle;
 	uint8_t bdaddr[6];
@@ -134,6 +141,7 @@ struct btconn {
 	uint16_t next_cid;
 	struct l2conn *l2conns;
 	struct cid_hook *cid_hooks;
+	struct rfcomm_channel_hook *rfcomm_channel_hooks;
 	struct btconn *next;
 	void *smp_data;
 };
@@ -233,6 +241,13 @@ static void btconn_free(struct btconn *conn)
 		free(hook);
 	}
 
+	while (conn->rfcomm_channel_hooks) {
+		struct rfcomm_channel_hook *hook = conn->rfcomm_channel_hooks;
+
+		conn->rfcomm_channel_hooks = hook->next;
+		free(hook);
+	}
+
 	free(conn);
 }
 
@@ -1547,6 +1562,18 @@ static struct cid_hook *find_cid_hook(struct btconn *conn, uint16_t cid)
 	return NULL;
 }
 
+static struct rfcomm_channel_hook *find_rfcomm_channel_hook(struct btconn *conn,
+							uint16_t channel)
+{
+	struct rfcomm_channel_hook *hook;
+
+	for (hook = conn->rfcomm_channel_hooks; hook != NULL; hook = hook->next)
+		if (hook->channel == channel)
+			return hook;
+
+	return NULL;
+}
+
 static void rfcomm_ua_send(struct bthost *bthost, struct btconn *conn,
 			struct l2conn *l2conn, uint8_t cr, uint8_t dlci)
 {
@@ -1801,9 +1828,6 @@ static void rfcomm_uih_recv(struct bthost *bthost, struct btconn *conn,
 	if (len < sizeof(*hdr))
 		return;
 
-	if (RFCOMM_GET_DLCI(hdr->address))
-		return;
-
 	if (RFCOMM_TEST_EA(hdr->length))
 		hdr_len = sizeof(*hdr);
 	else
@@ -1814,7 +1838,19 @@ static void rfcomm_uih_recv(struct bthost *bthost, struct btconn *conn,
 
 	p = data + hdr_len;
 
-	rfcomm_mcc_recv(bthost, conn, l2conn, p, len - hdr_len);
+	if (RFCOMM_GET_DLCI(hdr->address)) {
+		struct rfcomm_channel_hook *hook;
+
+		hook = find_rfcomm_channel_hook(conn,
+					RFCOMM_GET_CHANNEL(hdr->address));
+		if (!hook)
+			return;
+
+		hook->func(p, len - hdr_len - sizeof(uint8_t),
+							hook->user_data);
+	} else {
+		rfcomm_mcc_recv(bthost, conn, l2conn, p, len - hdr_len);
+	}
 }
 
 static void process_rfcomm(struct bthost *bthost, struct btconn *conn,
@@ -2112,6 +2148,32 @@ bool bthost_connect_rfcomm(struct bthost *bthost, uint16_t handle,
 					&req, sizeof(req), NULL, NULL);
 }
 
+void bthost_add_rfcomm_channel_hook(struct bthost *bthost, uint16_t handle,
+					uint8_t channel,
+					bthost_rfcomm_channel_hook_func_t func,
+					void *user_data)
+{
+	struct rfcomm_channel_hook *hook;
+	struct btconn *conn;
+
+	conn = bthost_find_conn(bthost, handle);
+	if (!conn)
+		return;
+
+	hook = malloc(sizeof(*hook));
+	if (!hook)
+		return;
+
+	memset(hook, 0, sizeof(*hook));
+
+	hook->channel = channel;
+	hook->func = func;
+	hook->user_data = user_data;
+
+	hook->next = conn->rfcomm_channel_hooks;
+	conn->rfcomm_channel_hooks = hook;
+}
+
 void bthost_stop(struct bthost *bthost)
 {
 	if (bthost->smp_data) {
diff --git a/emulator/bthost.h b/emulator/bthost.h
index a3c26a1..e922f0b 100644
--- a/emulator/bthost.h
+++ b/emulator/bthost.h
@@ -99,6 +99,15 @@ bool bthost_connect_rfcomm(struct bthost *bthost, uint16_t handle,
 				uint8_t channel, bthost_rfcomm_connect_cb func,
 				void *user_data);
 
+typedef void (*bthost_rfcomm_channel_hook_func_t) (const void *data,
+							uint16_t len,
+							void *user_data);
+
+void bthost_add_rfcomm_channel_hook(struct bthost *bthost, uint16_t handle,
+					uint8_t channel,
+					bthost_rfcomm_channel_hook_func_t func,
+					void *user_data);
+
 void bthost_start(struct bthost *bthost);
 void bthost_stop(struct bthost *bthost);
 
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCHv2 2/6] tools/rfcomm-tester: Add RFCOMM client write test case
  2014-02-18  7:50 [PATCHv2 0/6] RFCOMM data transfer support in bthost Marcin Kraglak
  2014-02-18  7:50 ` [PATCHv2 1/6] emulator/bthost: Add api to handle RFCOMM data on bthost Marcin Kraglak
@ 2014-02-18  7:50 ` Marcin Kraglak
  2014-02-18  7:50 ` [PATCHv2 3/6] tools/rfcomm-tester: Add RFCOMM server " Marcin Kraglak
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Marcin Kraglak @ 2014-02-18  7:50 UTC (permalink / raw)
  To: linux-bluetooth

This will test sending data through RFCOMM socket from client to server.
---
 tools/rfcomm-tester.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 58 insertions(+), 1 deletion(-)

diff --git a/tools/rfcomm-tester.c b/tools/rfcomm-tester.c
index 44df7e7..42355cf 100644
--- a/tools/rfcomm-tester.c
+++ b/tools/rfcomm-tester.c
@@ -57,6 +57,9 @@ struct rfcomm_client_data {
 	uint8_t server_channel;
 	uint8_t client_channel;
 	int expected_connect_err;
+	const uint8_t *send_data;
+	const uint8_t *read_data;
+	uint16_t data_len;
 };
 
 struct rfcomm_server_data {
@@ -294,6 +297,15 @@ const struct rfcomm_client_data connect_success = {
 	.client_channel = 0x0c
 };
 
+const uint8_t data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
+
+const struct rfcomm_client_data connect_send_success = {
+	.server_channel = 0x0c,
+	.client_channel = 0x0c,
+	.data_len = sizeof(data),
+	.send_data = data
+};
+
 const struct rfcomm_client_data connect_nval = {
 	.server_channel = 0x0c,
 	.client_channel = 0x0e,
@@ -389,6 +401,16 @@ static gboolean rc_connect_cb(GIOChannel *io, GIOCondition cond,
 		return false;
 	}
 
+	if (client_data->send_data) {
+		ssize_t ret;
+
+		ret = write(sk, client_data->send_data, client_data->data_len);
+		if (client_data->data_len != ret)
+			tester_test_failed();
+
+		return false;
+	}
+
 	if (err < 0)
 		tester_test_failed();
 	else
@@ -397,6 +419,38 @@ static gboolean rc_connect_cb(GIOChannel *io, GIOCondition cond,
 	return false;
 }
 
+static void client_hook_func(const void *data, uint16_t len,
+							void *user_data)
+{
+	struct test_data *test_data = tester_get_data();
+	const struct rfcomm_client_data *client_data = test_data->test_data;
+	ssize_t ret;
+
+	if (client_data->data_len != len) {
+		tester_test_failed();
+		return;
+	}
+
+	ret = memcmp(client_data->send_data, data, len);
+	if (ret)
+		tester_test_failed();
+	else
+		tester_test_passed();
+}
+
+static void rfcomm_connect_cb(uint16_t handle, uint16_t cid,
+						void *user_data, bool status)
+{
+	struct test_data *data = tester_get_data();
+	const struct rfcomm_client_data *client_data = data->test_data;
+	struct bthost *bthost = hciemu_client_get_host(data->hciemu);
+
+	if (client_data->send_data)
+		bthost_add_rfcomm_channel_hook(bthost, handle,
+						client_data->client_channel,
+						client_hook_func, NULL);
+}
+
 static void test_connect(const void *test_data)
 {
 	struct test_data *data = tester_get_data();
@@ -408,7 +462,7 @@ static void test_connect(const void *test_data)
 
 	bthost_add_l2cap_server(bthost, 0x0003, NULL, NULL);
 	bthost_add_rfcomm_server(bthost, client_data->server_channel,
-								NULL, NULL);
+						rfcomm_connect_cb, NULL);
 
 	master_addr = hciemu_get_master_bdaddr(data->hciemu);
 	client_addr = hciemu_get_client_bdaddr(data->hciemu);
@@ -540,6 +594,9 @@ int main(int argc, char *argv[])
 					setup_powered_client, test_basic);
 	test_rfcomm("Basic RFCOMM Socket Client - Success", &connect_success,
 					setup_powered_client, test_connect);
+	test_rfcomm("Basic RFCOMM Socket Client - Write Success",
+				&connect_send_success, setup_powered_client,
+				test_connect);
 	test_rfcomm("Basic RFCOMM Socket Client - Conn Refused",
 			&connect_nval, setup_powered_client, test_connect);
 	test_rfcomm("Basic RFCOMM Socket Server - Success", &listen_success,
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCHv2 3/6] tools/rfcomm-tester: Add RFCOMM server write test case
  2014-02-18  7:50 [PATCHv2 0/6] RFCOMM data transfer support in bthost Marcin Kraglak
  2014-02-18  7:50 ` [PATCHv2 1/6] emulator/bthost: Add api to handle RFCOMM data on bthost Marcin Kraglak
  2014-02-18  7:50 ` [PATCHv2 2/6] tools/rfcomm-tester: Add RFCOMM client write test case Marcin Kraglak
@ 2014-02-18  7:50 ` Marcin Kraglak
  2014-02-18  7:50 ` [PATCHv2 4/6] emulator/bthost: Add function to send RFCOMM UIH frames from bthost Marcin Kraglak
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Marcin Kraglak @ 2014-02-18  7:50 UTC (permalink / raw)
  To: linux-bluetooth

This will check data write from server to client.
---
 tools/rfcomm-tester.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 51 insertions(+)

diff --git a/tools/rfcomm-tester.c b/tools/rfcomm-tester.c
index 42355cf..765de88 100644
--- a/tools/rfcomm-tester.c
+++ b/tools/rfcomm-tester.c
@@ -66,6 +66,9 @@ struct rfcomm_server_data {
 	uint8_t server_channel;
 	uint8_t client_channel;
 	bool expected_status;
+	const uint8_t *send_data;
+	const uint8_t *read_data;
+	uint16_t data_len;
 };
 
 static void mgmt_debug(const char *str, void *user_data)
@@ -318,6 +321,14 @@ const struct rfcomm_server_data listen_success = {
 	.expected_status = true
 };
 
+const struct rfcomm_server_data listen_send_success = {
+	.server_channel = 0x0c,
+	.client_channel = 0x0c,
+	.expected_status = true,
+	.data_len = sizeof(data),
+	.send_data = data
+};
+
 const struct rfcomm_server_data listen_nval = {
 	.server_channel = 0x0c,
 	.client_channel = 0x0e,
@@ -438,6 +449,25 @@ static void client_hook_func(const void *data, uint16_t len,
 		tester_test_passed();
 }
 
+static void server_hook_func(const void *data, uint16_t len,
+							void *user_data)
+{
+	struct test_data *test_data = tester_get_data();
+	const struct rfcomm_server_data *server_data = test_data->test_data;
+	ssize_t ret;
+
+	if (server_data->data_len != len) {
+		tester_test_failed();
+		return;
+	}
+
+	ret = memcmp(server_data->send_data, data, len);
+	if (ret)
+		tester_test_failed();
+	else
+		tester_test_passed();
+}
+
 static void rfcomm_connect_cb(uint16_t handle, uint16_t cid,
 						void *user_data, bool status)
 {
@@ -490,7 +520,9 @@ static gboolean rfcomm_listen_cb(GIOChannel *io, GIOCondition cond,
 							gpointer user_data)
 {
 	struct test_data *data = tester_get_data();
+	const struct rfcomm_server_data *server_data = data->test_data;
 	int sk, new_sk;
+	ssize_t ret;
 
 	data->io_id = 0;
 
@@ -502,6 +534,16 @@ static gboolean rfcomm_listen_cb(GIOChannel *io, GIOCondition cond,
 		return false;
 	}
 
+	if (server_data->send_data) {
+		ret = write(new_sk, server_data->send_data,
+							server_data->data_len);
+		if (ret != server_data->data_len)
+			tester_test_failed();
+
+		close(new_sk);
+		return false;
+	}
+
 	close(new_sk);
 
 	tester_test_passed();
@@ -515,6 +557,9 @@ static void connection_cb(uint16_t handle, uint16_t cid, void *user_data,
 	struct test_data *data = tester_get_data();
 	const struct rfcomm_server_data *server_data = data->test_data;
 
+	if (server_data->data_len)
+		return;
+
 	if (server_data->expected_status == status)
 		tester_test_passed();
 	else
@@ -528,6 +573,9 @@ static void client_new_conn(uint16_t handle, void *user_data)
 	struct bthost *bthost;
 
 	bthost = hciemu_client_get_host(data->hciemu);
+	bthost_add_rfcomm_channel_hook(bthost, handle,
+						server_data->client_channel,
+						server_hook_func, NULL);
 	bthost_connect_rfcomm(bthost, handle, server_data->client_channel,
 						connection_cb, NULL);
 }
@@ -601,6 +649,9 @@ int main(int argc, char *argv[])
 			&connect_nval, setup_powered_client, test_connect);
 	test_rfcomm("Basic RFCOMM Socket Server - Success", &listen_success,
 					setup_powered_server, test_server);
+	test_rfcomm("Basic RFCOMM Socket Server - Write Success",
+				&listen_send_success, setup_powered_server,
+				test_server);
 	test_rfcomm("Basic RFCOMM Socket Server - Conn Refused", &listen_nval,
 					setup_powered_server, test_server);
 
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCHv2 4/6] emulator/bthost: Add function to send RFCOMM UIH frames from bthost
  2014-02-18  7:50 [PATCHv2 0/6] RFCOMM data transfer support in bthost Marcin Kraglak
                   ` (2 preceding siblings ...)
  2014-02-18  7:50 ` [PATCHv2 3/6] tools/rfcomm-tester: Add RFCOMM server " Marcin Kraglak
@ 2014-02-18  7:50 ` Marcin Kraglak
  2014-02-18  7:50 ` [PATCHv2 5/6] tools/rfcomm-tester: Add RFCOMM client read test case Marcin Kraglak
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Marcin Kraglak @ 2014-02-18  7:50 UTC (permalink / raw)
  To: linux-bluetooth

This will make RFCOMM UIH frame and fill with data passed by user.
It also adds bthost internal tracking of RFCOMM connections to store
cid and channel - user have to pass only conenction handle and channel.
---
 emulator/bthost.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 emulator/bthost.h |  4 +++
 2 files changed, 101 insertions(+)

diff --git a/emulator/bthost.c b/emulator/bthost.c
index 9bf9ad3..92c63cd 100644
--- a/emulator/bthost.c
+++ b/emulator/bthost.c
@@ -140,6 +140,7 @@ struct btconn {
 	uint8_t encr_mode;
 	uint16_t next_cid;
 	struct l2conn *l2conns;
+	struct rcconn *rcconns;
 	struct cid_hook *cid_hooks;
 	struct rfcomm_channel_hook *rfcomm_channel_hooks;
 	struct btconn *next;
@@ -153,6 +154,12 @@ struct l2conn {
 	struct l2conn *next;
 };
 
+struct rcconn {
+	uint8_t channel;
+	uint16_t scid;
+	struct rcconn *next;
+};
+
 struct l2cap_pending_req {
 	uint8_t ident;
 	bthost_l2cap_rsp_cb cb;
@@ -241,6 +248,13 @@ static void btconn_free(struct btconn *conn)
 		free(hook);
 	}
 
+	while (conn->rcconns) {
+		struct rcconn *rcconn = conn->rcconns;
+
+		conn->rcconns = rcconn->next;
+		free(rcconn);
+	}
+
 	while (conn->rfcomm_channel_hooks) {
 		struct rfcomm_channel_hook *hook = conn->rfcomm_channel_hooks;
 
@@ -299,6 +313,41 @@ static struct l2conn *bthost_add_l2cap_conn(struct bthost *bthost,
 	return l2conn;
 }
 
+static struct rcconn *bthost_add_rfcomm_conn(struct bthost *bthost,
+						struct btconn *conn,
+						struct l2conn *l2conn,
+						uint8_t channel)
+{
+	struct rcconn *rcconn;
+
+	rcconn = malloc(sizeof(*rcconn));
+	if (!rcconn)
+		return NULL;
+
+	memset(rcconn, 0, sizeof(*rcconn));
+
+	rcconn->channel = channel;
+	rcconn->scid = l2conn->scid;
+
+	rcconn->next = conn->rcconns;
+	conn->rcconns = rcconn;
+
+	return rcconn;
+}
+
+static struct rcconn *btconn_find_rfcomm_conn_by_channel(struct btconn *conn,
+								uint8_t chan)
+{
+	struct rcconn *rcconn;
+
+	for (rcconn = conn->rcconns; rcconn != NULL; rcconn = rcconn->next) {
+		if (rcconn->channel == chan)
+			return rcconn;
+	}
+
+	return NULL;
+}
+
 static struct l2conn *btconn_find_l2cap_conn_by_scid(struct btconn *conn,
 								uint16_t scid)
 {
@@ -1617,6 +1666,7 @@ static void rfcomm_sabm_recv(struct bthost *bthost, struct btconn *conn,
 
 	cb = bthost_find_rfcomm_cb_by_channel(bthost, chan);
 	if (!dlci || cb) {
+		bthost_add_rfcomm_conn(bthost, conn, l2conn, chan);
 		rfcomm_ua_send(bthost, conn, l2conn, 1, dlci);
 		if (cb && cb->func)
 			cb->func(conn->handle, l2conn->scid, cb->user_data,
@@ -1661,6 +1711,7 @@ static void rfcomm_ua_recv(struct bthost *bthost, struct btconn *conn,
 	type = RFCOMM_GET_TYPE(ua_hdr->control);
 
 	if (channel && conn_data && conn_data->channel == channel) {
+		bthost_add_rfcomm_conn(bthost, conn, l2conn, channel);
 		if (conn_data->cb)
 			conn_data->cb(conn->handle, l2conn->scid,
 						conn_data->user_data, true);
@@ -1672,6 +1723,8 @@ static void rfcomm_ua_recv(struct bthost *bthost, struct btconn *conn,
 	if (!conn_data || !RFCOMM_TEST_CR(type))
 		return;
 
+	bthost_add_rfcomm_conn(bthost, conn, l2conn, channel);
+
 	memset(buf, 0, sizeof(buf));
 
 	hdr = (struct rfcomm_hdr *) buf;
@@ -2174,6 +2227,50 @@ void bthost_add_rfcomm_channel_hook(struct bthost *bthost, uint16_t handle,
 	conn->rfcomm_channel_hooks = hook;
 }
 
+void bthost_send_rfcomm_data(struct bthost *bthost, uint16_t handle,
+					uint8_t channel, const void *data,
+					uint16_t len)
+{
+	struct btconn *conn;
+	struct rcconn *rcconn;
+	struct rfcomm_hdr *hdr;
+	uint8_t *uih_frame;
+	uint16_t uih_len;
+
+	conn = bthost_find_conn(bthost, handle);
+	if (!conn)
+		return;
+
+	rcconn = btconn_find_rfcomm_conn_by_channel(conn, channel);
+	if (!rcconn)
+		return;
+
+	if (len > 127)
+		uih_len = len + sizeof(struct rfcomm_cmd) + sizeof(uint8_t);
+	else
+		uih_len = len + sizeof(struct rfcomm_cmd);
+
+	uih_frame = malloc(uih_len);
+	if (!uih_frame)
+		return;
+
+	hdr = (struct rfcomm_hdr *) uih_frame;
+	hdr->address = RFCOMM_ADDR(1, channel * 2);
+	hdr->control = RFCOMM_CTRL(RFCOMM_UIH, 0);
+	if (len > 127) {
+		hdr->length  = RFCOMM_LEN16(cpu_to_le16(sizeof(*hdr) + len));
+		memcpy(uih_frame + sizeof(*hdr) + 1, data, len);
+	} else {
+		hdr->length  = RFCOMM_LEN8(sizeof(*hdr) + len);
+		memcpy(uih_frame + sizeof(*hdr), data, len);
+	}
+
+	uih_frame[uih_len - 1] = rfcomm_fcs((void *)hdr);
+	send_acl(bthost, handle, rcconn->scid, uih_frame, uih_len);
+
+	free(uih_frame);
+}
+
 void bthost_stop(struct bthost *bthost)
 {
 	if (bthost->smp_data) {
diff --git a/emulator/bthost.h b/emulator/bthost.h
index e922f0b..0d4594f 100644
--- a/emulator/bthost.h
+++ b/emulator/bthost.h
@@ -108,6 +108,10 @@ void bthost_add_rfcomm_channel_hook(struct bthost *bthost, uint16_t handle,
 					bthost_rfcomm_channel_hook_func_t func,
 					void *user_data);
 
+void bthost_send_rfcomm_data(struct bthost *bthost, uint16_t handle,
+					uint8_t channel, const void *data,
+					uint16_t len);
+
 void bthost_start(struct bthost *bthost);
 void bthost_stop(struct bthost *bthost);
 
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCHv2 5/6] tools/rfcomm-tester: Add RFCOMM client read test case
  2014-02-18  7:50 [PATCHv2 0/6] RFCOMM data transfer support in bthost Marcin Kraglak
                   ` (3 preceding siblings ...)
  2014-02-18  7:50 ` [PATCHv2 4/6] emulator/bthost: Add function to send RFCOMM UIH frames from bthost Marcin Kraglak
@ 2014-02-18  7:50 ` Marcin Kraglak
  2014-02-18  7:50 ` [PATCHv2 6/6] tools/rfcomm-tester: Add RFCOMM server " Marcin Kraglak
  2014-02-19 13:12 ` [PATCHv2 0/6] RFCOMM data transfer support in bthost Johan Hedberg
  6 siblings, 0 replies; 8+ messages in thread
From: Marcin Kraglak @ 2014-02-18  7:50 UTC (permalink / raw)
  To: linux-bluetooth

This will test reading data passed to RFCOMM socket on client side.
---
 tools/rfcomm-tester.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 46 insertions(+)

diff --git a/tools/rfcomm-tester.c b/tools/rfcomm-tester.c
index 765de88..4066553 100644
--- a/tools/rfcomm-tester.c
+++ b/tools/rfcomm-tester.c
@@ -51,6 +51,7 @@ struct test_data {
 	enum hciemu_type hciemu_type;
 	const void *test_data;
 	unsigned int io_id;
+	uint16_t conn_handle;
 };
 
 struct rfcomm_client_data {
@@ -309,6 +310,13 @@ const struct rfcomm_client_data connect_send_success = {
 	.send_data = data
 };
 
+const struct rfcomm_client_data connect_read_success = {
+	.server_channel = 0x0c,
+	.client_channel = 0x0c,
+	.data_len = sizeof(data),
+	.read_data = data
+};
+
 const struct rfcomm_client_data connect_nval = {
 	.server_channel = 0x0c,
 	.client_channel = 0x0e,
@@ -389,6 +397,31 @@ static int connect_rfcomm_sock(int sk, const bdaddr_t *bdaddr, uint8_t channel)
 	return 0;
 }
 
+static gboolean client_received_data(GIOChannel *io, GIOCondition cond,
+							gpointer user_data)
+{
+	struct test_data *data = tester_get_data();
+	const struct rfcomm_client_data *client_data = data->test_data;
+	int sk;
+	ssize_t ret;
+	char buf[248];
+
+	sk = g_io_channel_unix_get_fd(io);
+
+	ret = read(sk, buf, client_data->data_len);
+	if (client_data->data_len != ret) {
+		tester_test_failed();
+		return false;
+	}
+
+	if (memcmp(client_data->read_data, buf, client_data->data_len))
+		tester_test_failed();
+	else
+		tester_test_passed();
+
+	return false;
+}
+
 static gboolean rc_connect_cb(GIOChannel *io, GIOCondition cond,
 		gpointer user_data)
 {
@@ -420,6 +453,14 @@ static gboolean rc_connect_cb(GIOChannel *io, GIOCondition cond,
 			tester_test_failed();
 
 		return false;
+	} else if (client_data->read_data) {
+		g_io_add_watch(io, G_IO_IN, client_received_data, NULL);
+		bthost_send_rfcomm_data(hciemu_client_get_host(data->hciemu),
+						data->conn_handle,
+						client_data->client_channel,
+						client_data->read_data,
+						client_data->data_len);
+		return false;
 	}
 
 	if (err < 0)
@@ -479,6 +520,8 @@ static void rfcomm_connect_cb(uint16_t handle, uint16_t cid,
 		bthost_add_rfcomm_channel_hook(bthost, handle,
 						client_data->client_channel,
 						client_hook_func, NULL);
+	else if (client_data->read_data)
+		data->conn_handle = handle;
 }
 
 static void test_connect(const void *test_data)
@@ -645,6 +688,9 @@ int main(int argc, char *argv[])
 	test_rfcomm("Basic RFCOMM Socket Client - Write Success",
 				&connect_send_success, setup_powered_client,
 				test_connect);
+	test_rfcomm("Basic RFCOMM Socket Client - Read Success",
+				&connect_read_success, setup_powered_client,
+				test_connect);
 	test_rfcomm("Basic RFCOMM Socket Client - Conn Refused",
 			&connect_nval, setup_powered_client, test_connect);
 	test_rfcomm("Basic RFCOMM Socket Server - Success", &listen_success,
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCHv2 6/6] tools/rfcomm-tester: Add RFCOMM server read test case
  2014-02-18  7:50 [PATCHv2 0/6] RFCOMM data transfer support in bthost Marcin Kraglak
                   ` (4 preceding siblings ...)
  2014-02-18  7:50 ` [PATCHv2 5/6] tools/rfcomm-tester: Add RFCOMM client read test case Marcin Kraglak
@ 2014-02-18  7:50 ` Marcin Kraglak
  2014-02-19 13:12 ` [PATCHv2 0/6] RFCOMM data transfer support in bthost Johan Hedberg
  6 siblings, 0 replies; 8+ messages in thread
From: Marcin Kraglak @ 2014-02-18  7:50 UTC (permalink / raw)
  To: linux-bluetooth

It will test reading data passed to RFCOMM socket on server side.
---
 tools/rfcomm-tester.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 57 insertions(+), 1 deletion(-)

diff --git a/tools/rfcomm-tester.c b/tools/rfcomm-tester.c
index 4066553..71c1cf1 100644
--- a/tools/rfcomm-tester.c
+++ b/tools/rfcomm-tester.c
@@ -337,6 +337,14 @@ const struct rfcomm_server_data listen_send_success = {
 	.send_data = data
 };
 
+const struct rfcomm_server_data listen_read_success = {
+	.server_channel = 0x0c,
+	.client_channel = 0x0c,
+	.expected_status = true,
+	.data_len = sizeof(data),
+	.read_data = data
+};
+
 const struct rfcomm_server_data listen_nval = {
 	.server_channel = 0x0c,
 	.client_channel = 0x0e,
@@ -559,6 +567,31 @@ static void test_connect(const void *test_data)
 	tester_print("Connect in progress %d", sk);
 }
 
+static gboolean server_received_data(GIOChannel *io, GIOCondition cond,
+							gpointer user_data)
+{
+	struct test_data *data = tester_get_data();
+	const struct rfcomm_server_data *server_data = data->test_data;
+	char buf[1024];
+	ssize_t ret;
+	int sk;
+
+	sk = g_io_channel_unix_get_fd(io);
+
+	ret = read(sk, buf, server_data->data_len);
+	if (ret != server_data->data_len) {
+		tester_test_failed();
+		return false;
+	}
+
+	if (memcmp(buf, server_data->read_data, server_data->data_len))
+		tester_test_failed();
+	else
+		tester_test_passed();
+
+	return false;
+}
+
 static gboolean rfcomm_listen_cb(GIOChannel *io, GIOCondition cond,
 							gpointer user_data)
 {
@@ -585,6 +618,17 @@ static gboolean rfcomm_listen_cb(GIOChannel *io, GIOCondition cond,
 
 		close(new_sk);
 		return false;
+	} else if (server_data->read_data) {
+		GIOChannel *new_io;
+
+		new_io = g_io_channel_unix_new(new_sk);
+		g_io_channel_set_close_on_unref(new_io, TRUE);
+
+		data->io_id = g_io_add_watch(new_io, G_IO_IN,
+						server_received_data, NULL);
+
+		g_io_channel_unref(new_io);
+		return false;
 	}
 
 	close(new_sk);
@@ -599,9 +643,18 @@ static void connection_cb(uint16_t handle, uint16_t cid, void *user_data,
 {
 	struct test_data *data = tester_get_data();
 	const struct rfcomm_server_data *server_data = data->test_data;
+	struct bthost *bthost = hciemu_client_get_host(data->hciemu);
 
-	if (server_data->data_len)
+	if (server_data->read_data) {
+		data->conn_handle = handle;
+		bthost_send_rfcomm_data(bthost, data->conn_handle,
+						server_data->client_channel,
+						server_data->read_data,
+						server_data->data_len);
+		return;
+	} else if (server_data->data_len) {
 		return;
+	}
 
 	if (server_data->expected_status == status)
 		tester_test_passed();
@@ -698,6 +751,9 @@ int main(int argc, char *argv[])
 	test_rfcomm("Basic RFCOMM Socket Server - Write Success",
 				&listen_send_success, setup_powered_server,
 				test_server);
+	test_rfcomm("Basic RFCOMM Socket Server - Read Success",
+				&listen_read_success, setup_powered_server,
+				test_server);
 	test_rfcomm("Basic RFCOMM Socket Server - Conn Refused", &listen_nval,
 					setup_powered_server, test_server);
 
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCHv2 0/6] RFCOMM data transfer support in bthost
  2014-02-18  7:50 [PATCHv2 0/6] RFCOMM data transfer support in bthost Marcin Kraglak
                   ` (5 preceding siblings ...)
  2014-02-18  7:50 ` [PATCHv2 6/6] tools/rfcomm-tester: Add RFCOMM server " Marcin Kraglak
@ 2014-02-19 13:12 ` Johan Hedberg
  6 siblings, 0 replies; 8+ messages in thread
From: Johan Hedberg @ 2014-02-19 13:12 UTC (permalink / raw)
  To: Marcin Kraglak; +Cc: linux-bluetooth

Hi Marcin,

On Tue, Feb 18, 2014, Marcin Kraglak wrote:
> v2:
>  - Added rfcomm prefixes in API functions and internal structs
>  - Values returned by read() and write stored in local variables
> for clarity
>  - Few coding style fixes
> 
> Marcin Kraglak (6):
>   emulator/bthost: Add api to handle RFCOMM data on bthost
>   tools/rfcomm-tester: Add RFCOMM client write test case
>   tools/rfcomm-tester: Add RFCOMM server write test case
>   emulator/bthost: Add function to send RFCOMM UIH frames from bthost
>   tools/rfcomm-tester: Add RFCOMM client read test case
>   tools/rfcomm-tester: Add RFCOMM server read test case
> 
>  emulator/bthost.c     | 167 ++++++++++++++++++++++++++++++++++++++-
>  emulator/bthost.h     |  13 ++++
>  tools/rfcomm-tester.c | 212 +++++++++++++++++++++++++++++++++++++++++++++++++-
>  3 files changed, 387 insertions(+), 5 deletions(-)

All patches in this set have been applied. I also applied a couple of
extra cleanup/fix patches on top of it to avoid yet another review
round.

Johan

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2014-02-19 13:12 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-02-18  7:50 [PATCHv2 0/6] RFCOMM data transfer support in bthost Marcin Kraglak
2014-02-18  7:50 ` [PATCHv2 1/6] emulator/bthost: Add api to handle RFCOMM data on bthost Marcin Kraglak
2014-02-18  7:50 ` [PATCHv2 2/6] tools/rfcomm-tester: Add RFCOMM client write test case Marcin Kraglak
2014-02-18  7:50 ` [PATCHv2 3/6] tools/rfcomm-tester: Add RFCOMM server " Marcin Kraglak
2014-02-18  7:50 ` [PATCHv2 4/6] emulator/bthost: Add function to send RFCOMM UIH frames from bthost Marcin Kraglak
2014-02-18  7:50 ` [PATCHv2 5/6] tools/rfcomm-tester: Add RFCOMM client read test case Marcin Kraglak
2014-02-18  7:50 ` [PATCHv2 6/6] tools/rfcomm-tester: Add RFCOMM server " Marcin Kraglak
2014-02-19 13:12 ` [PATCHv2 0/6] RFCOMM data transfer support in bthost Johan Hedberg

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.