Linux bluetooth development
 help / color / mirror / Atom feed
* [PATCH 05/10] profiles/network: Move pan sdp record function bnep and make it global
From: Ravi kumar Veeramally @ 2013-12-11 10:13 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Ravi kumar Veeramally
In-Reply-To: <1386756825-934-1-git-send-email-ravikumar.veeramally@linux.intel.com>

Moving pan sdp record function bnep, it is required in android/pan.
Even though it is not exactly related to bnep, but bnep.h|c is dbus
free files and shared with android/*.
---
 profiles/network/bnep.c   | 129 ++++++++++++++++++++++++++++++++++++++++++++++
 profiles/network/bnep.h   |   2 +
 profiles/network/server.c | 128 +--------------------------------------------
 3 files changed, 132 insertions(+), 127 deletions(-)

diff --git a/profiles/network/bnep.c b/profiles/network/bnep.c
index 08037e6..bbccd87 100644
--- a/profiles/network/bnep.c
+++ b/profiles/network/bnep.c
@@ -39,6 +39,8 @@
 #include <bluetooth/bluetooth.h>
 #include <bluetooth/l2cap.h>
 #include <bluetooth/bnep.h>
+#include <bluetooth/sdp.h>
+#include <bluetooth/sdp_lib.h>
 
 #include <glib.h>
 
@@ -542,3 +544,130 @@ uint16_t bnep_setup_decode(struct bnep_setup_conn_req *req, uint16_t *dst,
 
 	return BNEP_SUCCESS;
 }
+
+sdp_record_t *pan_record(const char *name, uint16_t id, gboolean security)
+{
+	sdp_list_t *svclass, *pfseq, *apseq, *root, *aproto;
+	uuid_t root_uuid, pan, l2cap, bnep;
+	sdp_profile_desc_t profile[1];
+	sdp_list_t *proto[2];
+	sdp_data_t *v, *p;
+	uint16_t psm = BNEP_PSM, version = 0x0100;
+	uint16_t security_desc = (security ? 0x0001 : 0x0000);
+	uint16_t net_access_type = 0xfffe;
+	uint32_t max_net_access_rate = 0;
+	const char *desc = "Network service";
+	sdp_record_t *record;
+
+	record = sdp_record_alloc();
+	if (!record)
+		return NULL;
+
+	record->attrlist = NULL;
+	record->pattern = NULL;
+
+	switch (id) {
+	case BNEP_SVC_NAP:
+		sdp_uuid16_create(&pan, NAP_SVCLASS_ID);
+		svclass = sdp_list_append(NULL, &pan);
+		sdp_set_service_classes(record, svclass);
+
+		sdp_uuid16_create(&profile[0].uuid, NAP_PROFILE_ID);
+		profile[0].version = 0x0100;
+		pfseq = sdp_list_append(NULL, &profile[0]);
+		sdp_set_profile_descs(record, pfseq);
+
+		sdp_set_info_attr(record, name, NULL, desc);
+
+		sdp_attr_add_new(record, SDP_ATTR_NET_ACCESS_TYPE,
+					SDP_UINT16, &net_access_type);
+		sdp_attr_add_new(record, SDP_ATTR_MAX_NET_ACCESSRATE,
+					SDP_UINT32, &max_net_access_rate);
+		break;
+	case BNEP_SVC_GN:
+		sdp_uuid16_create(&pan, GN_SVCLASS_ID);
+		svclass = sdp_list_append(NULL, &pan);
+		sdp_set_service_classes(record, svclass);
+
+		sdp_uuid16_create(&profile[0].uuid, GN_PROFILE_ID);
+		profile[0].version = 0x0100;
+		pfseq = sdp_list_append(NULL, &profile[0]);
+		sdp_set_profile_descs(record, pfseq);
+
+		sdp_set_info_attr(record, name, NULL, desc);
+		break;
+	case BNEP_SVC_PANU:
+		sdp_uuid16_create(&pan, PANU_SVCLASS_ID);
+		svclass = sdp_list_append(NULL, &pan);
+		sdp_set_service_classes(record, svclass);
+
+		sdp_uuid16_create(&profile[0].uuid, PANU_PROFILE_ID);
+		profile[0].version = 0x0100;
+		pfseq = sdp_list_append(NULL, &profile[0]);
+		sdp_set_profile_descs(record, pfseq);
+
+		sdp_set_info_attr(record, name, NULL, desc);
+		break;
+	default:
+		sdp_record_free(record);
+		return NULL;
+	}
+
+	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
+	root = sdp_list_append(NULL, &root_uuid);
+	sdp_set_browse_groups(record, root);
+
+	sdp_uuid16_create(&l2cap, L2CAP_UUID);
+	proto[0] = sdp_list_append(NULL, &l2cap);
+	p = sdp_data_alloc(SDP_UINT16, &psm);
+	proto[0] = sdp_list_append(proto[0], p);
+	apseq    = sdp_list_append(NULL, proto[0]);
+
+	sdp_uuid16_create(&bnep, BNEP_UUID);
+	proto[1] = sdp_list_append(NULL, &bnep);
+	v = sdp_data_alloc(SDP_UINT16, &version);
+	proto[1] = sdp_list_append(proto[1], v);
+
+	/* Supported protocols */
+	{
+		uint16_t ptype[] = {
+			0x0800,  /* IPv4 */
+			0x0806,  /* ARP */
+		};
+		sdp_data_t *head, *pseq;
+		int p;
+
+		for (p = 0, head = NULL; p < 2; p++) {
+			sdp_data_t *data = sdp_data_alloc(SDP_UINT16,
+								&ptype[p]);
+			if (head)
+				sdp_seq_append(head, data);
+			else
+				head = data;
+		}
+		pseq = sdp_data_alloc(SDP_SEQ16, head);
+		proto[1] = sdp_list_append(proto[1], pseq);
+	}
+
+	apseq = sdp_list_append(apseq, proto[1]);
+
+	aproto = sdp_list_append(NULL, apseq);
+	sdp_set_access_protos(record, aproto);
+
+	sdp_add_lang_attr(record);
+
+	sdp_attr_add_new(record, SDP_ATTR_SECURITY_DESC,
+				SDP_UINT16, &security_desc);
+
+	sdp_data_free(p);
+	sdp_data_free(v);
+	sdp_list_free(apseq, NULL);
+	sdp_list_free(root, NULL);
+	sdp_list_free(aproto, NULL);
+	sdp_list_free(proto[0], NULL);
+	sdp_list_free(proto[1], NULL);
+	sdp_list_free(svclass, NULL);
+	sdp_list_free(pfseq, NULL);
+
+	return record;
+}
diff --git a/profiles/network/bnep.h b/profiles/network/bnep.h
index dd22c40..4f1f812 100644
--- a/profiles/network/bnep.h
+++ b/profiles/network/bnep.h
@@ -44,3 +44,5 @@ 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);
+
+sdp_record_t *pan_record(const char *name, uint16_t id, gboolean security);
diff --git a/profiles/network/server.c b/profiles/network/server.c
index 73741ec..95564c6 100644
--- a/profiles/network/server.c
+++ b/profiles/network/server.c
@@ -125,132 +125,6 @@ static struct network_server *find_server_by_uuid(GSList *list,
 	return NULL;
 }
 
-static sdp_record_t *server_record_new(const char *name, uint16_t id)
-{
-	sdp_list_t *svclass, *pfseq, *apseq, *root, *aproto;
-	uuid_t root_uuid, pan, l2cap, bnep;
-	sdp_profile_desc_t profile[1];
-	sdp_list_t *proto[2];
-	sdp_data_t *v, *p;
-	uint16_t psm = BNEP_PSM, version = 0x0100;
-	uint16_t security_desc = (security ? 0x0001 : 0x0000);
-	uint16_t net_access_type = 0xfffe;
-	uint32_t max_net_access_rate = 0;
-	const char *desc = "Network service";
-	sdp_record_t *record;
-
-	record = sdp_record_alloc();
-	if (!record)
-		return NULL;
-
-	record->attrlist = NULL;
-	record->pattern = NULL;
-
-	switch (id) {
-	case BNEP_SVC_NAP:
-		sdp_uuid16_create(&pan, NAP_SVCLASS_ID);
-		svclass = sdp_list_append(NULL, &pan);
-		sdp_set_service_classes(record, svclass);
-
-		sdp_uuid16_create(&profile[0].uuid, NAP_PROFILE_ID);
-		profile[0].version = 0x0100;
-		pfseq = sdp_list_append(NULL, &profile[0]);
-		sdp_set_profile_descs(record, pfseq);
-
-		sdp_set_info_attr(record, name, NULL, desc);
-
-		sdp_attr_add_new(record, SDP_ATTR_NET_ACCESS_TYPE,
-					SDP_UINT16, &net_access_type);
-		sdp_attr_add_new(record, SDP_ATTR_MAX_NET_ACCESSRATE,
-					SDP_UINT32, &max_net_access_rate);
-		break;
-	case BNEP_SVC_GN:
-		sdp_uuid16_create(&pan, GN_SVCLASS_ID);
-		svclass = sdp_list_append(NULL, &pan);
-		sdp_set_service_classes(record, svclass);
-
-		sdp_uuid16_create(&profile[0].uuid, GN_PROFILE_ID);
-		profile[0].version = 0x0100;
-		pfseq = sdp_list_append(NULL, &profile[0]);
-		sdp_set_profile_descs(record, pfseq);
-
-		sdp_set_info_attr(record, name, NULL, desc);
-		break;
-	case BNEP_SVC_PANU:
-		sdp_uuid16_create(&pan, PANU_SVCLASS_ID);
-		svclass = sdp_list_append(NULL, &pan);
-		sdp_set_service_classes(record, svclass);
-
-		sdp_uuid16_create(&profile[0].uuid, PANU_PROFILE_ID);
-		profile[0].version = 0x0100;
-		pfseq = sdp_list_append(NULL, &profile[0]);
-		sdp_set_profile_descs(record, pfseq);
-
-		sdp_set_info_attr(record, name, NULL, desc);
-		break;
-	default:
-		sdp_record_free(record);
-		return NULL;
-	}
-
-	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
-	root = sdp_list_append(NULL, &root_uuid);
-	sdp_set_browse_groups(record, root);
-
-	sdp_uuid16_create(&l2cap, L2CAP_UUID);
-	proto[0] = sdp_list_append(NULL, &l2cap);
-	p = sdp_data_alloc(SDP_UINT16, &psm);
-	proto[0] = sdp_list_append(proto[0], p);
-	apseq    = sdp_list_append(NULL, proto[0]);
-
-	sdp_uuid16_create(&bnep, BNEP_UUID);
-	proto[1] = sdp_list_append(NULL, &bnep);
-	v = sdp_data_alloc(SDP_UINT16, &version);
-	proto[1] = sdp_list_append(proto[1], v);
-
-	/* Supported protocols */
-	{
-		uint16_t ptype[] = {
-			0x0800,  /* IPv4 */
-			0x0806,  /* ARP */
-		};
-		sdp_data_t *head, *pseq;
-		int p;
-
-		for (p = 0, head = NULL; p < 2; p++) {
-			sdp_data_t *data = sdp_data_alloc(SDP_UINT16, &ptype[p]);
-			if (head)
-				sdp_seq_append(head, data);
-			else
-				head = data;
-		}
-		pseq = sdp_data_alloc(SDP_SEQ16, head);
-		proto[1] = sdp_list_append(proto[1], pseq);
-	}
-
-	apseq = sdp_list_append(apseq, proto[1]);
-
-	aproto = sdp_list_append(NULL, apseq);
-	sdp_set_access_protos(record, aproto);
-
-	sdp_add_lang_attr(record);
-
-	sdp_attr_add_new(record, SDP_ATTR_SECURITY_DESC,
-				SDP_UINT16, &security_desc);
-
-	sdp_data_free(p);
-	sdp_data_free(v);
-	sdp_list_free(apseq, NULL);
-	sdp_list_free(root, NULL);
-	sdp_list_free(aproto, NULL);
-	sdp_list_free(proto[0], NULL);
-	sdp_list_free(proto[1], NULL);
-	sdp_list_free(svclass, NULL);
-	sdp_list_free(pfseq, NULL);
-
-	return record;
-}
-
 static int server_connadd(struct network_server *ns,
 				struct network_session *session,
 				uint16_t dst_role)
@@ -497,7 +371,7 @@ static uint32_t register_server_record(struct network_server *ns)
 {
 	sdp_record_t *record;
 
-	record = server_record_new(ns->name, ns->id);
+	record = pan_record(ns->name, ns->id, security);
 	if (!record) {
 		error("Unable to allocate new service record");
 		return 0;
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH 06/10] android/pan: Remove channel unref which causing disconnection
From: Ravi kumar Veeramally @ 2013-12-11 10:13 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Ravi kumar Veeramally
In-Reply-To: <1386756825-934-1-git-send-email-ravikumar.veeramally@linux.intel.com>

Channel unreferencing here causing calling watchdog_cb and eventually
connection is dismissed immediately. Channel is already freed
in bnep.c:free_bnep_connect().
---
 android/pan.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/android/pan.c b/android/pan.c
index f74f1a7..a9557a0 100644
--- a/android/pan.c
+++ b/android/pan.c
@@ -156,8 +156,6 @@ static void bnep_conn_cb(GIOChannel *chan, char *iface, int err, void *data)
 
 	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;
 }
 
 static void connect_cb(GIOChannel *chan, GError *err, gpointer data)
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH 07/10] android/pan: Fix missing cleanup calls
From: Ravi kumar Veeramally @ 2013-12-11 10:13 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Ravi kumar Veeramally
In-Reply-To: <1386756825-934-1-git-send-email-ravikumar.veeramally@linux.intel.com>

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

diff --git a/android/pan.c b/android/pan.c
index a9557a0..1ed7b04 100644
--- a/android/pan.c
+++ b/android/pan.c
@@ -128,6 +128,8 @@ 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);
 	pan_device_free(dev);
 
@@ -142,6 +144,7 @@ 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);
 		pan_device_free(dev);
 		return;
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH 08/10] android/pan: Fix minor white space
From: Ravi kumar Veeramally @ 2013-12-11 10:13 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Ravi kumar Veeramally
In-Reply-To: <1386756825-934-1-git-send-email-ravikumar.veeramally@linux.intel.com>

---
 android/pan.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/android/pan.c b/android/pan.c
index 1ed7b04..0783357 100644
--- a/android/pan.c
+++ b/android/pan.c
@@ -257,7 +257,7 @@ static void bt_pan_connect(const void *buf, uint16_t len)
 	devices = g_slist_append(devices, dev);
 	bt_pan_notify_conn_state(dev, HAL_PAN_STATE_CONNECTING);
 
-	status =  HAL_STATUS_SUCCESS;
+	status = HAL_STATUS_SUCCESS;
 
 failed:
 	ipc_send_rsp(HAL_SERVICE_ID_PAN, HAL_OP_PAN_CONNECT, status);
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH 09/10] android/pan: Free connected pan devices on profile unregister call
From: Ravi kumar Veeramally @ 2013-12-11 10:13 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Ravi kumar Veeramally
In-Reply-To: <1386756825-934-1-git-send-email-ravikumar.veeramally@linux.intel.com>

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

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


^ permalink raw reply related

* [PATCH 10/10] android/pan: Add PAN NAP sdp record fo server role
From: Ravi kumar Veeramally @ 2013-12-11 10:13 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Ravi kumar Veeramally
In-Reply-To: <1386756825-934-1-git-send-email-ravikumar.veeramally@linux.intel.com>

Adding PAN profile NAP SDP record on profile register call and
remove on unregister call.
---
 android/pan.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/android/pan.c b/android/pan.c
index 29b0a54..a6a8e27 100644
--- a/android/pan.c
+++ b/android/pan.c
@@ -44,9 +44,12 @@
 #include "utils.h"
 #include "bluetooth.h"
 
+#define SVC_HINT_CAPTURING 0x08
+
 static bdaddr_t adapter_addr;
 GSList *devices = NULL;
 uint8_t local_role = HAL_PAN_ROLE_NONE;
+static uint32_t record_id = 0;
 
 struct pan_device {
 	char		iface[16];
@@ -343,6 +346,7 @@ static const struct ipc_handler cmd_handlers[] = {
 
 bool bt_pan_register(const bdaddr_t *addr)
 {
+	sdp_record_t *rec = NULL;
 	int err;
 
 	DBG("");
@@ -355,6 +359,21 @@ bool bt_pan_register(const bdaddr_t *addr)
 		return false;
 	}
 
+	rec = pan_record("bnepnap", BNEP_SVC_NAP, TRUE);
+	if (!rec) {
+		bnep_cleanup();
+		return false;
+	}
+
+	if (bt_adapter_add_record(rec, SVC_HINT_CAPTURING) < 0) {
+		error("Failed to register on PAN record");
+		sdp_record_free(rec);
+		bnep_cleanup();
+		return false;
+	}
+
+	record_id = rec->handle;
+
 	ipc_register(HAL_SERVICE_ID_PAN, cmd_handlers,
 						G_N_ELEMENTS(cmd_handlers));
 
@@ -373,6 +392,8 @@ void bt_pan_unregister(void)
 {
 	DBG("");
 
+	bt_adapter_remove_record(record_id);
+
 	g_slist_foreach(devices, free_pan_devices, NULL);
 	devices = NULL;
 	bnep_cleanup();
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH 1/9] android/bluetooth: Add support for reporting adapter type property
From: Szymon Janc @ 2013-12-11 10:31 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

This allows to get property with adapter type.
---
 android/bluetooth.c | 32 +++++++++++++++++++++++++++++---
 android/hal-msg.h   |  4 ++++
 2 files changed, 33 insertions(+), 3 deletions(-)

diff --git a/android/bluetooth.c b/android/bluetooth.c
index e456f3c..82003fd 100644
--- a/android/bluetooth.c
+++ b/android/bluetooth.c
@@ -1674,13 +1674,39 @@ static uint8_t get_adapter_class(void)
 	return HAL_STATUS_SUCCESS;
 }
 
+static uint8_t settings2type(void)
+{
+	bool bredr, le;
+
+	bredr = adapter.current_settings & MGMT_SETTING_BREDR;
+	le = adapter.current_settings & MGMT_SETTING_LE;
+
+	if (bredr && le)
+		return HAL_TYPE_DUAL;
+
+	if (bredr && !le)
+		return HAL_TYPE_BREDR;
+
+	if (!bredr && le)
+		return HAL_TYPE_LE;
+
+	return 0;
+}
+
 static uint8_t get_adapter_type(void)
 {
-	DBG("Not implemented");
+	uint8_t type;
 
-	/* TODO: Add implementation */
+	DBG("");
 
-	return HAL_STATUS_FAILED;
+	type = settings2type();
+
+	if (!type)
+		return HAL_STATUS_FAILED;
+
+	send_adapter_property(HAL_PROP_ADAPTER_TYPE, sizeof(type), &type);
+
+	return HAL_STATUS_SUCCESS;
 }
 
 static uint8_t get_adapter_service_rec(void)
diff --git a/android/hal-msg.h b/android/hal-msg.h
index 80c4a25..3be91aa 100644
--- a/android/hal-msg.h
+++ b/android/hal-msg.h
@@ -116,6 +116,10 @@ struct hal_cmd_get_adapter_prop {
 #define HAL_ADAPTER_SCAN_MODE_CONN		0x01
 #define HAL_ADAPTER_SCAN_MODE_CONN_DISC	0x02
 
+#define HAL_TYPE_BREDR				0x01
+#define HAL_TYPE_LE				0x02
+#define HAL_TYPE_DUAL				0x03
+
 #define HAL_OP_SET_ADAPTER_PROP		0x05
 struct hal_cmd_set_adapter_prop {
 	uint8_t  type;
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH 2/9] android/bluetooth: Add support for adapter bonded devices property
From: Szymon Janc @ 2013-12-11 10:31 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1386757887-29018-1-git-send-email-szymon.janc@tieto.com>

This allows to get property with list of bonded devices.
---
 android/bluetooth.c | 21 ++++++++++++++++++---
 1 file changed, 18 insertions(+), 3 deletions(-)

diff --git a/android/bluetooth.c b/android/bluetooth.c
index 82003fd..b6ef3e6 100644
--- a/android/bluetooth.c
+++ b/android/bluetooth.c
@@ -1729,11 +1729,26 @@ static uint8_t get_adapter_scan_mode(void)
 
 static uint8_t get_adapter_bonded_devices(void)
 {
-	DBG("Not implemented");
+	uint8_t buf[sizeof(bdaddr_t) * g_slist_length(devices)];
+	int i = 0;
+	GSList *l;
 
-	/* TODO: Add implementation */
+	DBG("");
 
-	return HAL_STATUS_FAILED;
+	for (l = devices; l; l = g_slist_next(l)) {
+		struct device *dev = l->data;
+
+		if (dev->bond_state != HAL_BOND_STATE_BONDED)
+			continue;
+
+		bdaddr2android(&dev->bdaddr, buf + (i * sizeof(bdaddr_t)));
+		i++;
+	}
+
+	send_adapter_property(HAL_PROP_ADAPTER_BONDED_DEVICES,
+						i * sizeof(bdaddr_t), buf);
+
+	return HAL_STATUS_SUCCESS;
 }
 
 static uint8_t get_adapter_discoverable_timeout(void)
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH 3/9] android/bluetooth: Add support for remote device friendly name
From: Szymon Janc @ 2013-12-11 10:31 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1386757887-29018-1-git-send-email-szymon.janc@tieto.com>

This allows to get and set remote device property with friendly name.
Storage support is still missing.
---
 android/bluetooth.c | 26 ++++++++++++++++++--------
 1 file changed, 18 insertions(+), 8 deletions(-)

diff --git a/android/bluetooth.c b/android/bluetooth.c
index b6ef3e6..e32ddd6 100644
--- a/android/bluetooth.c
+++ b/android/bluetooth.c
@@ -95,6 +95,7 @@ struct device {
 	bdaddr_t bdaddr;
 	int bond_state;
 	char *name;
+	char *friendly_name;
 };
 
 struct browse_req {
@@ -2282,11 +2283,13 @@ static uint8_t get_device_service_rec(struct device *dev)
 
 static uint8_t get_device_friendly_name(struct device *dev)
 {
-	DBG("Not implemented");
+	if (!dev->friendly_name)
+		return HAL_STATUS_FAILED;
 
-	/* TODO */
+	send_device_property(&dev->bdaddr, HAL_PROP_DEVICE_FRIENDLY_NAME,
+				strlen(dev->friendly_name), dev->friendly_name);
 
-	return HAL_STATUS_FAILED;
+	return HAL_STATUS_SUCCESS;
 }
 
 static uint8_t get_device_rssi(struct device *dev)
@@ -2377,13 +2380,20 @@ failed:
 								status);
 }
 
-static uint8_t set_device_friendly_name(struct device *dev)
+static uint8_t set_device_friendly_name(struct device *dev, const uint8_t *val,
+								uint16_t len)
 {
-	DBG("Not implemented");
+	DBG("");
 
-	/* TODO */
+	g_free(dev->friendly_name);
+	dev->friendly_name = g_strndup((const char *) val, len);
 
-	return HAL_STATUS_FAILED;
+	/* TODO store friendly name */
+
+	send_device_property(&dev->bdaddr, HAL_PROP_DEVICE_FRIENDLY_NAME,
+				strlen(dev->friendly_name), dev->friendly_name);
+
+	return HAL_STATUS_SUCCESS;
 }
 
 static uint8_t set_device_version_info(struct device *dev)
@@ -2419,7 +2429,7 @@ static void handle_set_remote_device_prop_cmd(const void *buf, uint16_t len)
 
 	switch (cmd->type) {
 	case HAL_PROP_DEVICE_FRIENDLY_NAME:
-		status = set_device_friendly_name(l->data);
+		status = set_device_friendly_name(l->data, cmd->val, cmd->len);
 		break;
 	case HAL_PROP_DEVICE_VERSION_INFO:
 		status = set_device_version_info(l->data);
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH 4/9] android/bluetooth: Free devices on service unregister
From: Szymon Janc @ 2013-12-11 10:31 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1386757887-29018-1-git-send-email-szymon.janc@tieto.com>

There is no need to keep devices list in memory if service was
unregistered.
---
 android/bluetooth.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/android/bluetooth.c b/android/bluetooth.c
index e32ddd6..d6cefb7 100644
--- a/android/bluetooth.c
+++ b/android/bluetooth.c
@@ -154,6 +154,13 @@ static struct device *create_device(const bdaddr_t *bdaddr)
 	return dev;
 }
 
+static void free_device(struct device *dev)
+{
+	g_free(dev->name);
+	g_free(dev->friendly_name);
+	g_free(dev);
+}
+
 static struct device *get_device(const bdaddr_t *bdaddr)
 {
 	struct device *dev;
@@ -2557,5 +2564,8 @@ void bt_bluetooth_unregister(void)
 {
 	DBG("");
 
+	g_slist_free_full(devices, (GDestroyNotify) free_device);
+	devices = NULL;
+
 	ipc_unregister(HAL_SERVICE_ID_CORE);
 }
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH 5/9] android/bluetooth: Add support for remote device class
From: Szymon Janc @ 2013-12-11 10:31 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1386757887-29018-1-git-send-email-szymon.janc@tieto.com>

This allows to cache remote device CoD and get it with get property
command.
---
 android/bluetooth.c | 19 ++++++++++++-------
 1 file changed, 12 insertions(+), 7 deletions(-)

diff --git a/android/bluetooth.c b/android/bluetooth.c
index d6cefb7..0515468 100644
--- a/android/bluetooth.c
+++ b/android/bluetooth.c
@@ -96,6 +96,7 @@ struct device {
 	int bond_state;
 	char *name;
 	char *friendly_name;
+	uint32_t class;
 };
 
 struct browse_req {
@@ -594,6 +595,7 @@ static void pin_code_request_callback(uint16_t index, uint16_t length,
 {
 	const struct mgmt_ev_pin_code_request *ev = param;
 	struct hal_ev_pin_request hal_ev;
+	struct device *dev;
 	char dst[18];
 
 	if (length < sizeof(*ev)) {
@@ -603,19 +605,21 @@ static void pin_code_request_callback(uint16_t index, uint16_t length,
 
 	ba2str(&ev->addr.bdaddr, dst);
 
+	dev = get_device(&ev->addr.bdaddr);
+
 	/* Workaround for Android Bluetooth.apk issue: send remote
 	 * device property */
-	get_device_name(get_device(&ev->addr.bdaddr));
+	get_device_name(dev);
 
 	set_device_bond_state(&ev->addr.bdaddr, HAL_STATUS_SUCCESS,
 						HAL_BOND_STATE_BONDING);
 
 	DBG("%s type %u secure %u", dst, ev->addr.type, ev->secure);
 
-	/* TODO CoD of remote devices should probably be cached
-	 * Name we already send in remote device prop */
+	/* Name already sent in remote device prop */
 	memset(&hal_ev, 0, sizeof(hal_ev));
 	bdaddr2android(&ev->addr.bdaddr, hal_ev.bdaddr);
+	hal_ev.class_of_dev = dev->class;
 
 	ipc_send_notif(HAL_SERVICE_ID_BLUETOOTH, HAL_EV_PIN_REQUEST,
 						sizeof(hal_ev), &hal_ev);
@@ -810,6 +814,8 @@ static void update_found_device(const bdaddr_t *bdaddr, uint8_t bdaddr_type,
 	}
 
 	if (eir.class) {
+		dev->class = eir.class;
+
 		size += fill_hal_prop(buf + size, HAL_PROP_DEVICE_CLASS,
 						sizeof(eir.class), &eir.class);
 		(*num_prop)++;
@@ -2263,11 +2269,10 @@ static uint8_t get_device_uuids(struct device *dev)
 
 static uint8_t get_device_class(struct device *dev)
 {
-	DBG("Not implemented");
+	send_device_property(&dev->bdaddr, HAL_PROP_DEVICE_CLASS,
+					sizeof(dev->class), &dev->class);
 
-	/* TODO */
-
-	return HAL_STATUS_FAILED;
+	return HAL_STATUS_SUCCESS;
 }
 
 static uint8_t get_device_type(struct device *dev)
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH 6/9] android/bluetooth: Add support for remote device RSSI
From: Szymon Janc @ 2013-12-11 10:31 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1386757887-29018-1-git-send-email-szymon.janc@tieto.com>

This allows to cache remote device RSSI and get it with get property
command.
---
 android/bluetooth.c | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/android/bluetooth.c b/android/bluetooth.c
index 0515468..254ccb4 100644
--- a/android/bluetooth.c
+++ b/android/bluetooth.c
@@ -97,6 +97,7 @@ struct device {
 	char *name;
 	char *friendly_name;
 	uint32_t class;
+	int32_t rssi;
 };
 
 struct browse_req {
@@ -822,6 +823,8 @@ static void update_found_device(const bdaddr_t *bdaddr, uint8_t bdaddr_type,
 	}
 
 	if (rssi) {
+		dev->rssi = rssi;
+
 		size += fill_hal_prop(buf + size, HAL_PROP_DEVICE_RSSI,
 							sizeof(rssi), &rssi);
 		(*num_prop)++;
@@ -2306,11 +2309,13 @@ static uint8_t get_device_friendly_name(struct device *dev)
 
 static uint8_t get_device_rssi(struct device *dev)
 {
-	DBG("Not implemented");
+	if (!dev->rssi)
+		return HAL_STATUS_FAILED;
 
-	/* TODO */
+	send_device_property(&dev->bdaddr, HAL_PROP_DEVICE_RSSI,
+						sizeof(dev->rssi), &dev->rssi);
 
-	return HAL_STATUS_FAILED;
+	return HAL_STATUS_SUCCESS;
 }
 
 static uint8_t get_device_version_info(struct device *dev)
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH 7/9] android/bluetooth: Add support for get remote device properties command
From: Szymon Janc @ 2013-12-11 10:31 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1386757887-29018-1-git-send-email-szymon.janc@tieto.com>

This allows to get all properties of specified remote device.
---
 android/bluetooth.c | 28 ++++++++++++++++++++++++++--
 1 file changed, 26 insertions(+), 2 deletions(-)

diff --git a/android/bluetooth.c b/android/bluetooth.c
index 254ccb4..ffe1120 100644
--- a/android/bluetooth.c
+++ b/android/bluetooth.c
@@ -2338,10 +2338,34 @@ static uint8_t get_device_timestamp(struct device *dev)
 
 static void handle_get_remote_device_props_cmd(const void *buf, uint16_t len)
 {
-	/* TODO */
+	const struct hal_cmd_get_remote_device_props *cmd = buf;
+	uint8_t status;
+	bdaddr_t addr;
+	GSList *l;
+
+	android2bdaddr(cmd->bdaddr, &addr);
+
+	l = g_slist_find_custom(devices, &addr, bdaddr_cmp);
+	if (!l) {
+		status = HAL_STATUS_INVALID;
+		goto failed;
+	}
 
+	get_device_name(l->data);
+	get_device_uuids(l->data);
+	get_device_class(l->data);
+	get_device_type(l->data);
+	get_device_service_rec(l->data);
+	get_device_friendly_name(l->data);
+	get_device_rssi(l->data);
+	get_device_version_info(l->data);
+	get_device_timestamp(l->data);
+
+	status = HAL_STATUS_SUCCESS;
+
+failed:
 	ipc_send_rsp(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_GET_REMOTE_DEVICE_PROPS,
-							HAL_STATUS_FAILED);
+									status);
 }
 
 static void handle_get_remote_device_prop_cmd(const void *buf, uint16_t len)
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH 8/9] android/bluetooth: Add support for remote device type property
From: Szymon Janc @ 2013-12-11 10:31 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1386757887-29018-1-git-send-email-szymon.janc@tieto.com>

This makes daemon store remote device address type to be able to handle
remote device type property.
---
 android/bluetooth.c | 37 ++++++++++++++++++++++++++++---------
 1 file changed, 28 insertions(+), 9 deletions(-)

diff --git a/android/bluetooth.c b/android/bluetooth.c
index ffe1120..b139ff7 100644
--- a/android/bluetooth.c
+++ b/android/bluetooth.c
@@ -93,6 +93,7 @@ static struct {
 
 struct device {
 	bdaddr_t bdaddr;
+	uint8_t bdaddr_type;
 	int bond_state;
 	char *name;
 	char *friendly_name;
@@ -135,7 +136,7 @@ static struct device *find_device(const bdaddr_t *bdaddr)
 	return NULL;
 }
 
-static struct device *create_device(const bdaddr_t *bdaddr)
+static struct device *create_device(const bdaddr_t *bdaddr, uint8_t type)
 {
 	struct device *dev;
 	char addr[18];
@@ -146,6 +147,7 @@ static struct device *create_device(const bdaddr_t *bdaddr)
 	dev = g_new0(struct device, 1);
 
 	bacpy(&dev->bdaddr, bdaddr);
+	dev->bdaddr_type = type;
 	dev->bond_state = HAL_BOND_STATE_NONE;
 
 	/* use address for name, will be change if one is present
@@ -163,7 +165,7 @@ static void free_device(struct device *dev)
 	g_free(dev);
 }
 
-static struct device *get_device(const bdaddr_t *bdaddr)
+static struct device *get_device(const bdaddr_t *bdaddr, uint8_t type)
 {
 	struct device *dev;
 
@@ -171,7 +173,7 @@ static struct device *get_device(const bdaddr_t *bdaddr)
 	if (dev)
 		return dev;
 
-	return create_device(bdaddr);
+	return create_device(bdaddr, type);
 }
 
 static  void send_adapter_property(uint8_t type, uint16_t len, const void *val)
@@ -369,7 +371,9 @@ static void set_device_bond_state(const bdaddr_t *addr, uint8_t status,
 
 	struct device *dev;
 
-	dev = get_device(addr);
+	dev = find_device(addr);
+	if (!dev)
+		return;
 
 	if (dev->bond_state != state) {
 		dev->bond_state = state;
@@ -606,7 +610,7 @@ static void pin_code_request_callback(uint16_t index, uint16_t length,
 
 	ba2str(&ev->addr.bdaddr, dst);
 
-	dev = get_device(&ev->addr.bdaddr);
+	dev = get_device(&ev->addr.bdaddr, BDADDR_BREDR);
 
 	/* Workaround for Android Bluetooth.apk issue: send remote
 	 * device property */
@@ -769,6 +773,14 @@ static int fill_hal_prop(void *buf, uint8_t type, uint16_t len,
 	return sizeof(*prop) + len;
 }
 
+static uint8_t bdaddr_type2android(uint8_t type)
+{
+	if (type == BDADDR_BREDR)
+		return HAL_TYPE_BREDR;
+
+	return HAL_TYPE_LE;
+}
+
 static void update_found_device(const bdaddr_t *bdaddr, uint8_t bdaddr_type,
 					int8_t rssi, bool confirm,
 					const uint8_t *data, uint8_t data_len)
@@ -789,8 +801,9 @@ static void update_found_device(const bdaddr_t *bdaddr, uint8_t bdaddr_type,
 	if (!dev) {
 		struct hal_ev_device_found *ev = (void *) buf;
 		bdaddr_t android_bdaddr;
+		uint8_t android_type;
 
-		dev = create_device(bdaddr);
+		dev = create_device(bdaddr, bdaddr_type);
 
 		size += sizeof(*ev);
 
@@ -802,6 +815,11 @@ static void update_found_device(const bdaddr_t *bdaddr, uint8_t bdaddr_type,
 		size += fill_hal_prop(buf + size, HAL_PROP_DEVICE_ADDR,
 				sizeof(android_bdaddr), &android_bdaddr);
 		(*num_prop)++;
+
+		android_type = bdaddr_type2android(dev->bdaddr_type);
+		size += fill_hal_prop(buf + size, HAL_PROP_DEVICE_TYPE,
+					sizeof(android_type), &android_type);
+		(*num_prop)++;
 	} else {
 		struct hal_ev_remote_device_props *ev = (void *) buf;
 
@@ -2280,11 +2298,12 @@ static uint8_t get_device_class(struct device *dev)
 
 static uint8_t get_device_type(struct device *dev)
 {
-	DBG("Not implemented");
+	uint8_t type = bdaddr_type2android(dev->bdaddr_type);
 
-	/* TODO */
+	send_device_property(&dev->bdaddr, HAL_PROP_DEVICE_TYPE,
+							sizeof(type), &type);
 
-	return HAL_STATUS_FAILED;
+	return HAL_STATUS_SUCCESS;
 }
 
 static uint8_t get_device_service_rec(struct device *dev)
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH 9/9] android/bluetooth: Code style and whitespace cleanup
From: Szymon Janc @ 2013-12-11 10:31 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1386757887-29018-1-git-send-email-szymon.janc@tieto.com>

This fix some random style or whitespace damages. Also moves statics
after last type definition.
---
 android/bluetooth.c | 63 ++++++++++++++++++++++++++++-------------------------
 1 file changed, 33 insertions(+), 30 deletions(-)

diff --git a/android/bluetooth.c b/android/bluetooth.c
index b139ff7..4bb2c92 100644
--- a/android/bluetooth.c
+++ b/android/bluetooth.c
@@ -52,20 +52,37 @@
 
 /* Default to DisplayYesNo */
 #define DEFAULT_IO_CAPABILITY 0x01
+
 /* Default discoverable timeout 120sec as in Android */
 #define DEFAULT_DISCOVERABLE_TIMEOUT 120
 
 #define BASELEN_PROP_CHANGED (sizeof(struct hal_ev_adapter_props_changed) \
-				+ (sizeof(struct hal_property)))
+					+ (sizeof(struct hal_property)))
 
 static uint16_t option_index = MGMT_INDEX_NONE;
 
 #define BASELEN_REMOTE_DEV_PROP (sizeof(struct hal_ev_remote_device_props) \
 					+ sizeof(struct hal_property))
-/* This list contains addresses which are asked for records */
-static GSList *browse_reqs;
 
-static struct mgmt *mgmt_if = NULL;
+struct device {
+	bdaddr_t bdaddr;
+	uint8_t bdaddr_type;
+
+	int bond_state;
+
+	char *name;
+	char *friendly_name;
+
+	uint32_t class;
+	int32_t rssi;
+};
+
+struct browse_req {
+	bdaddr_t bdaddr;
+	GSList *uuids;
+	int search_uuid;
+	int reconnect_attempt;
+};
 
 static struct {
 	uint16_t index;
@@ -91,23 +108,6 @@ static struct {
 	.uuids = NULL,
 };
 
-struct device {
-	bdaddr_t bdaddr;
-	uint8_t bdaddr_type;
-	int bond_state;
-	char *name;
-	char *friendly_name;
-	uint32_t class;
-	int32_t rssi;
-};
-
-struct browse_req {
-	bdaddr_t bdaddr;
-	GSList *uuids;
-	int search_uuid;
-	int reconnect_attempt;
-};
-
 static const uint16_t uuid_list[] = {
 	L2CAP_UUID,
 	PNP_INFO_SVCLASS_ID,
@@ -115,8 +115,12 @@ static const uint16_t uuid_list[] = {
 	0
 };
 
+static struct mgmt *mgmt_if = NULL;
 static GSList *devices = NULL;
 
+/* This list contains addresses which are asked for records */
+static GSList *browse_reqs;
+
 static int bdaddr_cmp(gconstpointer a, gconstpointer b)
 {
 	const bdaddr_t *bda = a;
@@ -349,7 +353,6 @@ static void store_link_key(const bdaddr_t *dst, const uint8_t *key,
 					uint8_t type, uint8_t pin_length)
 {
 	/* TODO store link key */
-
 }
 
 static void send_bond_state_change(const bdaddr_t *addr, uint8_t status,
@@ -368,7 +371,6 @@ static void send_bond_state_change(const bdaddr_t *addr, uint8_t status,
 static void set_device_bond_state(const bdaddr_t *addr, uint8_t status,
 								int state)
 {
-
 	struct device *dev;
 
 	dev = find_device(addr);
@@ -570,6 +572,7 @@ static void new_link_key_callback(uint16_t index, uint16_t length,
 
 	browse_remote_sdp(&addr->bdaddr);
 }
+
 static  void send_device_property(const bdaddr_t *bdaddr, uint8_t type,
 						uint16_t len, const void *val)
 {
@@ -693,7 +696,8 @@ static void user_passkey_request_callback(uint16_t index, uint16_t length,
 }
 
 static void user_passkey_notify_callback(uint16_t index, uint16_t length,
-					const void *param, void *user_data)
+							const void *param,
+							void *user_data)
 {
 	const struct mgmt_ev_passkey_notify *ev = param;
 	char dst[18];
@@ -713,8 +717,7 @@ static void user_passkey_notify_callback(uint16_t index, uint16_t length,
 	set_device_bond_state(&ev->addr.bdaddr, HAL_STATUS_SUCCESS,
 						HAL_BOND_STATE_BONDING);
 
-	send_ssp_request(&ev->addr.bdaddr, HAL_SSP_VARIANT_NOTIF,
-								ev->passkey);
+	send_ssp_request(&ev->addr.bdaddr, HAL_SSP_VARIANT_NOTIF, ev->passkey);
 }
 
 static void mgmt_discovering_event(uint16_t index, uint16_t length,
@@ -760,7 +763,6 @@ static void confirm_device_name(const bdaddr_t *addr, uint8_t addr_type)
 		error("Failed to send confirm name request");
 }
 
-
 static int fill_hal_prop(void *buf, uint8_t type, uint16_t len,
 							const void *val)
 {
@@ -813,7 +815,8 @@ static void update_found_device(const bdaddr_t *bdaddr, uint8_t bdaddr_type,
 		bdaddr2android(bdaddr, &android_bdaddr);
 
 		size += fill_hal_prop(buf + size, HAL_PROP_DEVICE_ADDR,
-				sizeof(android_bdaddr), &android_bdaddr);
+							sizeof(android_bdaddr),
+							&android_bdaddr);
 		(*num_prop)++;
 
 		android_type = bdaddr_type2android(dev->bdaddr_type);
@@ -932,7 +935,8 @@ static void mgmt_device_connected_event(uint16_t index, uint16_t length,
 }
 
 static void mgmt_device_disconnected_event(uint16_t index, uint16_t length,
-					const void *param, void *user_data)
+							const void *param,
+							void *user_data)
 {
 	const struct mgmt_ev_device_disconnected *ev = param;
 	struct hal_ev_acl_state_changed hal_ev;
@@ -1699,7 +1703,6 @@ static uint8_t get_adapter_name(void)
 	return HAL_STATUS_SUCCESS;
 }
 
-
 static uint8_t get_adapter_class(void)
 {
 	DBG("");
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH v4 1/7] android/tester: Add android-tester
From: Marcin Kraglak @ 2013-12-11 10:46 UTC (permalink / raw)
  To: linux-bluetooth

This commit add android-tester.c to tree and Makefile.am.
This will contain set of unit tests for testing android daemon.
---
 .gitignore               |  1 +
 android/Makefile.am      |  4 ++++
 android/android-tester.c | 21 +++++++++++++++++++++
 3 files changed, 26 insertions(+)
 create mode 100644 android/android-tester.c

diff --git a/.gitignore b/.gitignore
index 2d3435a..c570728 100644
--- a/.gitignore
+++ b/.gitignore
@@ -107,3 +107,4 @@ unit/test-*.trs
 android/system-emulator
 android/bluetoothd
 android/haltest
+android/android-tester
diff --git a/android/Makefile.am b/android/Makefile.am
index df04762..0768985 100644
--- a/android/Makefile.am
+++ b/android/Makefile.am
@@ -83,6 +83,10 @@ android_haltest_CFLAGS = $(AM_CFLAGS) -I$(srcdir)/android \
 
 android_haltest_LDFLAGS = -pthread
 
+noinst_PROGRAMS += android/android-tester
+
+android_android_tester_SOURCES = android/android-tester.c
+
 endif
 
 EXTRA_DIST += android/Android.mk android/hal-ipc-api.txt android/README \
diff --git a/android/android-tester.c b/android/android-tester.c
new file mode 100644
index 0000000..f5c42b0
--- /dev/null
+++ b/android/android-tester.c
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2013 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+int main(int argc, char *argv[])
+{
+	return 0;
+}
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH v4 2/7] android/tester: Add pre-setup and post-teardown routines
From: Marcin Kraglak @ 2013-12-11 10:46 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1386758797-1809-1-git-send-email-marcin.kraglak@tieto.com>

This will add hciemu initialization and cleanup. These functions
will be called to create hci emulator and cleanup it.
---
 android/Makefile.am      |  10 ++-
 android/android-tester.c | 183 ++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 191 insertions(+), 2 deletions(-)

diff --git a/android/Makefile.am b/android/Makefile.am
index 0768985..5364c2e 100644
--- a/android/Makefile.am
+++ b/android/Makefile.am
@@ -85,7 +85,15 @@ android_haltest_LDFLAGS = -pthread
 
 noinst_PROGRAMS += android/android-tester
 
-android_android_tester_SOURCES = android/android-tester.c
+android_android_tester_SOURCES = emulator/btdev.h emulator/btdev.c \
+				emulator/bthost.h emulator/bthost.c \
+				src/shared/util.h src/shared/util.c \
+				src/shared/mgmt.h src/shared/mgmt.c \
+				src/shared/hciemu.h src/shared/hciemu.c \
+				src/shared/tester.h src/shared/tester.c \
+				android/android-tester.c
+
+android_android_tester_LDADD = lib/libbluetooth-internal.la @GLIB_LIBS@
 
 endif
 
diff --git a/android/android-tester.c b/android/android-tester.c
index f5c42b0..498da22 100644
--- a/android/android-tester.c
+++ b/android/android-tester.c
@@ -15,7 +15,188 @@
  *
  */
 
+#include <unistd.h>
+
+#include <glib.h>
+
+#include "lib/bluetooth.h"
+#include "lib/mgmt.h"
+
+#include "src/shared/tester.h"
+#include "src/shared/mgmt.h"
+#include "src/shared/hciemu.h"
+
+struct generic_data {
+};
+
+struct test_data {
+	struct mgmt *mgmt;
+	uint16_t mgmt_index;
+	struct hciemu *hciemu;
+	enum hciemu_type hciemu_type;
+	const struct generic_data *test_data;
+};
+
+static void read_info_callback(uint8_t status, uint16_t length,
+					const void *param, void *user_data)
+{
+	struct test_data *data = tester_get_data();
+	const struct mgmt_rp_read_info *rp = param;
+	char addr[18];
+	uint16_t manufacturer;
+	uint32_t supported_settings, current_settings;
+
+	tester_print("Read Info callback");
+	tester_print("  Status: 0x%02x", status);
+
+	if (status || !param) {
+		tester_pre_setup_failed();
+		return;
+	}
+
+	ba2str(&rp->bdaddr, addr);
+	manufacturer = btohs(rp->manufacturer);
+	supported_settings = btohl(rp->supported_settings);
+	current_settings = btohl(rp->current_settings);
+
+	tester_print("  Address: %s", addr);
+	tester_print("  Version: 0x%02x", rp->version);
+	tester_print("  Manufacturer: 0x%04x", manufacturer);
+	tester_print("  Supported settings: 0x%08x", supported_settings);
+	tester_print("  Current settings: 0x%08x", current_settings);
+	tester_print("  Class: 0x%02x%02x%02x",
+			rp->dev_class[2], rp->dev_class[1], rp->dev_class[0]);
+	tester_print("  Name: %s", rp->name);
+	tester_print("  Short name: %s", rp->short_name);
+
+	if (strcmp(hciemu_get_address(data->hciemu), addr)) {
+		tester_pre_setup_failed();
+		return;
+	}
+
+	tester_pre_setup_complete();
+}
+
+static void index_added_callback(uint16_t index, uint16_t length,
+					const void *param, void *user_data)
+{
+	struct test_data *data = tester_get_data();
+
+	tester_print("Index Added callback");
+	tester_print("  Index: 0x%04x", index);
+
+	data->mgmt_index = index;
+
+	mgmt_send(data->mgmt, MGMT_OP_READ_INFO, data->mgmt_index, 0, NULL,
+					read_info_callback, NULL, NULL);
+}
+
+static void index_removed_callback(uint16_t index, uint16_t length,
+					const void *param, void *user_data)
+{
+	struct test_data *data = tester_get_data();
+
+	tester_print("Index Removed callback");
+	tester_print("  Index: 0x%04x", index);
+
+	if (index != data->mgmt_index)
+		return;
+
+	mgmt_unregister_index(data->mgmt, data->mgmt_index);
+
+	mgmt_unref(data->mgmt);
+	data->mgmt = NULL;
+
+	tester_post_teardown_complete();
+}
+
+static void read_index_list_callback(uint8_t status, uint16_t length,
+					const void *param, void *user_data)
+{
+	struct test_data *data = tester_get_data();
+
+	tester_print("Read Index List callback");
+	tester_print("  Status: 0x%02x", status);
+
+	if (status || !param) {
+		tester_pre_setup_failed();
+		return;
+	}
+
+	mgmt_register(data->mgmt, MGMT_EV_INDEX_ADDED, MGMT_INDEX_NONE,
+					index_added_callback, NULL, NULL);
+
+	mgmt_register(data->mgmt, MGMT_EV_INDEX_REMOVED, MGMT_INDEX_NONE,
+					index_removed_callback, NULL, NULL);
+
+	data->hciemu = hciemu_new(data->hciemu_type);
+	if (!data->hciemu) {
+		tester_warn("Failed to setup HCI emulation");
+		tester_pre_setup_failed();
+		return;
+	}
+
+	tester_print("New hciemu instance created");
+}
+
+static void test_pre_setup(const void *test_data)
+{
+	struct test_data *data = tester_get_data();
+
+	if (!tester_use_debug())
+		fclose(stderr);
+
+	data->mgmt = mgmt_new_default();
+	if (!data->mgmt) {
+		tester_warn("Failed to setup management interface");
+		tester_pre_setup_failed();
+		return;
+	}
+
+	mgmt_send(data->mgmt, MGMT_OP_READ_INDEX_LIST, MGMT_INDEX_NONE, 0,
+				NULL, read_index_list_callback, NULL, NULL);
+}
+
+static void test_post_teardown(const void *test_data)
+{
+	struct test_data *data = tester_get_data();
+
+	hciemu_unref(data->hciemu);
+	data->hciemu = NULL;
+}
+
+static void setup_base(const void *test_data)
+{
+	tester_setup_failed();
+}
+
+static void teardown(const void *test_data)
+{
+	tester_teardown_complete();
+}
+
+static void controller_setup(const void *test_data)
+{
+}
+
+#define test_bredrle(name, data, test_setup, test, test_teardown) \
+	do { \
+		struct test_data *user; \
+		user = g_malloc0(sizeof(struct test_data)); \
+		if (!user) \
+			break; \
+		user->hciemu_type = HCIEMU_TYPE_BREDRLE; \
+		user->test_data = data; \
+		tester_add_full(name, data, test_pre_setup, test_setup, \
+				test, test_teardown, test_post_teardown, \
+							3, user, g_free); \
+	} while (0)
+
 int main(int argc, char *argv[])
 {
-	return 0;
+	tester_init(&argc, &argv);
+
+	test_bredrle("Test Init", NULL, setup_base, controller_setup, teardown);
+
+	return tester_run();
 }
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH v4 3/7] android/tester: Start emulator in new process
From: Marcin Kraglak @ 2013-12-11 10:46 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1386758797-1809-1-git-send-email-marcin.kraglak@tieto.com>

This is needed because bluetooth->init call is blocking,
and we have to emulate normal behaviour of android environment.
That process will exit if it won't receive any message in 2 sec
or when bluetoothd will exit. Main tester thread will wait for
this process in teardown method.
---
 android/android-tester.c | 132 ++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 131 insertions(+), 1 deletion(-)

diff --git a/android/android-tester.c b/android/android-tester.c
index 498da22..ad7aa39 100644
--- a/android/android-tester.c
+++ b/android/android-tester.c
@@ -15,9 +15,15 @@
  *
  */
 
+#include <stdlib.h>
 #include <unistd.h>
 
 #include <glib.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/un.h>
+#include <libgen.h>
 
 #include "lib/bluetooth.h"
 #include "lib/mgmt.h"
@@ -29,14 +35,20 @@
 struct generic_data {
 };
 
+#define WAIT_FOR_SIGNAL_TIME 2 /* in seconds */
+#define EMULATOR_SIGNAL "emulator_started"
+
 struct test_data {
 	struct mgmt *mgmt;
 	uint16_t mgmt_index;
 	struct hciemu *hciemu;
 	enum hciemu_type hciemu_type;
 	const struct generic_data *test_data;
+	pid_t bluetoothd_pid;
 };
 
+static char exec_dir[PATH_MAX + 1];
+
 static void read_info_callback(uint8_t status, uint16_t length,
 					const void *param, void *user_data)
 {
@@ -165,13 +177,129 @@ static void test_post_teardown(const void *test_data)
 	data->hciemu = NULL;
 }
 
+static void bluetoothd_start(int hci_index)
+{
+	char prg_name[PATH_MAX + 1];
+	char index[8];
+	char *prg_argv[4];
+
+	snprintf(prg_name, sizeof(prg_name), "%s/%s", exec_dir, "bluetoothd");
+	snprintf(index, sizeof(index), "%d", hci_index);
+
+	prg_argv[0] = prg_name;
+	prg_argv[1] = "-i";
+	prg_argv[2] = index;
+	prg_argv[3] = NULL;
+
+	if (!tester_use_debug())
+		fclose(stderr);
+
+	execve(prg_argv[0], prg_argv, NULL);
+}
+
+static void emulator(int pipe, int hci_index)
+{
+	static const char SYSTEM_SOCKET_PATH[] = "\0android_system";
+	char buf[1024];
+	struct sockaddr_un addr;
+	struct timeval tv;
+	int fd;
+	ssize_t len;
+
+	fd = socket(PF_LOCAL, SOCK_DGRAM | SOCK_CLOEXEC, 0);
+	if (fd < 0)
+		goto failed;
+
+	tv.tv_sec = WAIT_FOR_SIGNAL_TIME;
+	tv.tv_usec = 0;
+	setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(tv));
+
+	memset(&addr, 0, sizeof(addr));
+	addr.sun_family = AF_UNIX;
+	memcpy(addr.sun_path, SYSTEM_SOCKET_PATH, sizeof(SYSTEM_SOCKET_PATH));
+
+	if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
+		perror("Failed to bind system socket");
+		goto failed;
+	}
+
+	len = write(pipe, EMULATOR_SIGNAL, sizeof(EMULATOR_SIGNAL));
+
+	if (len != sizeof(EMULATOR_SIGNAL))
+		goto failed;
+
+	memset(buf, 0, sizeof(buf));
+
+	len = read(fd, buf, sizeof(buf));
+	if (len <= 0 || (strcmp(buf, "ctl.start=bluetoothd")))
+		goto failed;
+
+	close(pipe);
+	close(fd);
+	bluetoothd_start(hci_index);
+
+failed:
+	close(pipe);
+	close(fd);
+}
+
+static void setup(struct test_data *data)
+{
+	int signal_fd[2];
+	char buf[1024];
+	pid_t pid;
+	int len;
+
+	if (pipe(signal_fd)) {
+		tester_setup_failed();
+		return;
+	}
+
+	pid = fork();
+
+	if (pid < 0) {
+		close(signal_fd[0]);
+		close(signal_fd[1]);
+		tester_setup_failed();
+		return;
+	}
+
+	if (pid == 0) {
+		if (!tester_use_debug())
+			fclose(stderr);
+
+		close(signal_fd[0]);
+		emulator(signal_fd[1], data->mgmt_index);
+		exit(0);
+	}
+
+	close(signal_fd[1]);
+	data->bluetoothd_pid = pid;
+
+	len = read(signal_fd[0], buf, sizeof(buf));
+	if (len <= 0 || (strcmp(buf, EMULATOR_SIGNAL))) {
+		close(signal_fd[0]);
+		tester_setup_failed();
+		return;
+	}
+}
+
 static void setup_base(const void *test_data)
 {
-	tester_setup_failed();
+	struct test_data *data = tester_get_data();
+
+	setup(data);
+
+	tester_setup_complete();
 }
 
 static void teardown(const void *test_data)
 {
+	struct test_data *data = tester_get_data();
+
+	if (data->bluetoothd_pid)
+		waitpid(data->bluetoothd_pid, NULL, 0);
+
 	tester_teardown_complete();
 }
 
@@ -194,6 +322,8 @@ static void controller_setup(const void *test_data)
 
 int main(int argc, char *argv[])
 {
+	snprintf(exec_dir, sizeof(exec_dir), "%s", dirname(argv[0]));
+
 	tester_init(&argc, &argv);
 
 	test_bredrle("Test Init", NULL, setup_base, controller_setup, teardown);
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH v4 4/7] android/tester: Add stack initialization of stack in setup
From: Marcin Kraglak @ 2013-12-11 10:46 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1386758797-1809-1-git-send-email-marcin.kraglak@tieto.com>

This add stack initialization and cleanup in setup/teardown.
---
 android/Makefile.am      | 10 +++++++--
 android/android-tester.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 65 insertions(+), 2 deletions(-)

diff --git a/android/Makefile.am b/android/Makefile.am
index 5364c2e..f3e77c3 100644
--- a/android/Makefile.am
+++ b/android/Makefile.am
@@ -91,9 +91,15 @@ android_android_tester_SOURCES = emulator/btdev.h emulator/btdev.c \
 				src/shared/mgmt.h src/shared/mgmt.c \
 				src/shared/hciemu.h src/shared/hciemu.c \
 				src/shared/tester.h src/shared/tester.c \
-				android/android-tester.c
+				android/hal-utils.h android/hal-utils.c \
+				android/client/hwmodule.c android/android-tester.c
 
-android_android_tester_LDADD = lib/libbluetooth-internal.la @GLIB_LIBS@
+android_android_tester_CFLAGS = $(AM_CFLAGS) -I$(srcdir)/android
+
+android_android_tester_LDADD = lib/libbluetooth-internal.la \
+				android/libhal-internal.la @GLIB_LIBS@
+
+android_android_tester_LDFLAGS = -pthread
 
 endif
 
diff --git a/android/android-tester.c b/android/android-tester.c
index ad7aa39..15f8c61 100644
--- a/android/android-tester.c
+++ b/android/android-tester.c
@@ -32,6 +32,9 @@
 #include "src/shared/mgmt.h"
 #include "src/shared/hciemu.h"
 
+#include <hardware/hardware.h>
+#include <hardware/bluetooth.h>
+
 struct generic_data {
 };
 
@@ -45,6 +48,7 @@ struct test_data {
 	enum hciemu_type hciemu_type;
 	const struct generic_data *test_data;
 	pid_t bluetoothd_pid;
+	const bt_interface_t *if_bluetooth;
 };
 
 static char exec_dir[PATH_MAX + 1];
@@ -243,12 +247,32 @@ failed:
 	close(fd);
 }
 
+static bt_callbacks_t bt_callbacks = {
+	.size = sizeof(bt_callbacks),
+	.adapter_state_changed_cb = NULL,
+	.adapter_properties_cb = NULL,
+	.remote_device_properties_cb = NULL,
+	.device_found_cb = NULL,
+	.discovery_state_changed_cb = NULL,
+	.pin_request_cb = NULL,
+	.ssp_request_cb = NULL,
+	.bond_state_changed_cb = NULL,
+	.acl_state_changed_cb = NULL,
+	.thread_evt_cb = NULL,
+	.dut_mode_recv_cb = NULL,
+	.le_test_mode_cb = NULL
+};
+
 static void setup(struct test_data *data)
 {
+	const hw_module_t *module;
+	hw_device_t *device;
+	bt_status_t status;
 	int signal_fd[2];
 	char buf[1024];
 	pid_t pid;
 	int len;
+	int err;
 
 	if (pipe(signal_fd)) {
 		tester_setup_failed();
@@ -282,6 +306,33 @@ static void setup(struct test_data *data)
 		tester_setup_failed();
 		return;
 	}
+
+	close(signal_fd[0]);
+
+	err = hw_get_module(BT_HARDWARE_MODULE_ID, &module);
+	if (err) {
+		tester_setup_failed();
+		return;
+	}
+
+	err = module->methods->open(module, BT_HARDWARE_MODULE_ID, &device);
+	if (err) {
+		tester_setup_failed();
+		return;
+	}
+
+	data->if_bluetooth = ((bluetooth_device_t *)
+					device)->get_bluetooth_interface();
+	if (!data->if_bluetooth) {
+		tester_setup_failed();
+		return;
+	}
+
+	status = data->if_bluetooth->init(&bt_callbacks);
+	if (status != BT_STATUS_SUCCESS) {
+		data->if_bluetooth = NULL;
+		tester_setup_failed();
+	}
 }
 
 static void setup_base(const void *test_data)
@@ -297,6 +348,11 @@ static void teardown(const void *test_data)
 {
 	struct test_data *data = tester_get_data();
 
+	if (data->if_bluetooth) {
+		data->if_bluetooth->cleanup();
+		data->if_bluetooth = NULL;
+	}
+
 	if (data->bluetoothd_pid)
 		waitpid(data->bluetoothd_pid, NULL, 0);
 
@@ -305,6 +361,7 @@ static void teardown(const void *test_data)
 
 static void controller_setup(const void *test_data)
 {
+	tester_test_passed();
 }
 
 #define test_bredrle(name, data, test_setup, test, test_teardown) \
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH v4 5/7] android/tester: Make HAL logging wrapper print to stderr instead of stdout
From: Marcin Kraglak @ 2013-12-11 10:46 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1386758797-1809-1-git-send-email-marcin.kraglak@tieto.com>

From: Szymon Janc <szymon.janc@tieto.com>

This is used for testing and for user it makes no difference. This
will allow to switch on/off verbose logging from automated android
tester.

---
 android/hal-log.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/android/hal-log.h b/android/hal-log.h
index 9bd024d..63ff61b 100644
--- a/android/hal-log.h
+++ b/android/hal-log.h
@@ -25,7 +25,7 @@
 #define LOG_WARN " W"
 #define LOG_ERROR " E"
 #define LOG_DEBUG " D"
-#define ALOG(pri, tag, fmt, arg...) printf(tag pri": " fmt"\n", ##arg)
+#define ALOG(pri, tag, fmt, arg...) fprintf(stderr, tag pri": " fmt"\n", ##arg)
 #endif
 
 #define info(fmt, arg...) ALOG(LOG_INFO, LOG_TAG, fmt, ##arg)
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH v4 6/7] android/tester: Add basic enable test
From: Marcin Kraglak @ 2013-12-11 10:46 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Grzegorz Kolodziejczyk
In-Reply-To: <1386758797-1809-1-git-send-email-marcin.kraglak@tieto.com>

From: Grzegorz Kolodziejczyk <grzegorz.kolodziejczyk@tieto.com>

---
 android/android-tester.c | 227 ++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 225 insertions(+), 2 deletions(-)

diff --git a/android/android-tester.c b/android/android-tester.c
index 15f8c61..0dc1edf 100644
--- a/android/android-tester.c
+++ b/android/android-tester.c
@@ -35,7 +35,32 @@
 #include <hardware/hardware.h>
 #include <hardware/bluetooth.h>
 
+#define adapter_props adapter_prop_bdaddr, adapter_prop_bdname, \
+			adapter_prop_uuids, adapter_prop_cod, \
+			adapter_prop_scan_mode, adapter_prop_disc_timeout
+
+/*
+ * those are assigned to HAL methods and callbacks, we use ID later
+ * on mapped in switch-case due to different functions prototypes.
+ */
+
+enum hal_bluetooth_callbacks_id {
+	adapter_test_end,
+	adapter_state_changed_on,
+	adapter_state_changed_off,
+	adapter_prop_bdaddr,
+	adapter_prop_bdname,
+	adapter_prop_uuids,
+	adapter_prop_cod,
+	adapter_prop_scan_mode,
+	adapter_prop_disc_timeout,
+	adapter_prop_service_record,
+	adapter_prop_bonded_devices
+};
+
 struct generic_data {
+	uint32_t expect_settings_set;
+	uint8_t expected_hal_callbacks[];
 };
 
 #define WAIT_FOR_SIGNAL_TIME 2 /* in seconds */
@@ -44,15 +69,100 @@ struct generic_data {
 struct test_data {
 	struct mgmt *mgmt;
 	uint16_t mgmt_index;
+	unsigned int mgmt_settings_id;
 	struct hciemu *hciemu;
 	enum hciemu_type hciemu_type;
 	const struct generic_data *test_data;
 	pid_t bluetoothd_pid;
 	const bt_interface_t *if_bluetooth;
+
+	bool mgmt_settings_set;
+	bool hal_cb_called;
+
+	GSList *expected_callbacks;
 };
 
 static char exec_dir[PATH_MAX + 1];
 
+static void test_update_state(void)
+{
+	struct test_data *data = tester_get_data();
+
+	if (data->mgmt_settings_set && data->hal_cb_called)
+		tester_test_passed();
+}
+
+static void test_mgmt_settings_set(struct test_data *data)
+{
+	data->mgmt_settings_set = true;
+
+	test_update_state();
+}
+
+static void command_generic_new_settings(uint16_t index, uint16_t length,
+					const void *param, void *user_data)
+{
+	struct test_data *data = tester_get_data();
+	uint32_t settings;
+
+	if (length != 4) {
+		tester_warn("Invalid parameter size for new settings event");
+		tester_test_failed();
+		return;
+	}
+
+	settings = bt_get_le32(param);
+
+	if ((settings & data->test_data->expect_settings_set) !=
+					data->test_data->expect_settings_set)
+		return;
+
+	test_mgmt_settings_set(data);
+	mgmt_unregister(data->mgmt, data->mgmt_settings_id);
+}
+
+static void hal_cb_init(struct test_data *data)
+{
+	unsigned int i = 0;
+
+	while (data->test_data->expected_hal_callbacks[i]) {
+						data->expected_callbacks =
+				g_slist_append(data->expected_callbacks,
+		GINT_TO_POINTER(data->test_data->expected_hal_callbacks[i]));
+		i++;
+	}
+}
+
+static void mgmt_cb_init(struct test_data *data)
+{
+	if (!data->test_data->expect_settings_set)
+		test_mgmt_settings_set(data);
+	else
+		data->mgmt_settings_id = mgmt_register(data->mgmt,
+					MGMT_EV_NEW_SETTINGS, data->mgmt_index,
+				command_generic_new_settings, NULL, NULL);
+}
+
+static int get_expected_hal_cb(void)
+{
+	struct test_data *data = tester_get_data();
+
+	return GPOINTER_TO_INT(data->expected_callbacks->data);
+}
+
+static void remove_expected_hal_cb(void)
+{
+	struct test_data *data = tester_get_data();
+
+	data->expected_callbacks = g_slist_remove(data->expected_callbacks,
+						data->expected_callbacks->data);
+
+	if (!data->expected_callbacks)
+		data->hal_cb_called = true;
+
+	test_update_state();
+}
+
 static void read_info_callback(uint8_t status, uint16_t length,
 					const void *param, void *user_data)
 {
@@ -247,10 +357,107 @@ failed:
 	close(fd);
 }
 
+static void adapter_state_changed_cb(bt_state_t state)
+{
+	switch (get_expected_hal_cb()) {
+	case adapter_state_changed_on:
+		if (state == BT_STATE_ON)
+			remove_expected_hal_cb();
+		else
+			tester_test_failed();
+		break;
+	default:
+		break;
+	}
+}
+
+static void adapter_properties_cb(bt_status_t status, int num_properties,
+						bt_property_t *properties)
+{
+	enum hal_bluetooth_callbacks_id hal_cb;
+	int i;
+
+	for (i = 0; i < num_properties; i++) {
+		hal_cb = get_expected_hal_cb();
+		switch (properties[i].type) {
+		case BT_PROPERTY_BDADDR:
+			if (hal_cb != adapter_prop_bdaddr) {
+				tester_test_failed();
+				return;
+			}
+			remove_expected_hal_cb();
+			break;
+		case BT_PROPERTY_BDNAME:
+			if (hal_cb != adapter_prop_bdname) {
+				tester_test_failed();
+				return;
+			}
+			remove_expected_hal_cb();
+			break;
+		case BT_PROPERTY_UUIDS:
+			if (hal_cb != adapter_prop_uuids) {
+				tester_test_failed();
+				return;
+			}
+			remove_expected_hal_cb();
+			break;
+		case BT_PROPERTY_CLASS_OF_DEVICE:
+			if (hal_cb != adapter_prop_cod) {
+				tester_test_failed();
+				return;
+			}
+			remove_expected_hal_cb();
+			break;
+		case BT_PROPERTY_TYPE_OF_DEVICE:
+			if (hal_cb != adapter_prop_bdaddr) {
+				tester_test_failed();
+				return;
+			}
+			remove_expected_hal_cb();
+			break;
+		case BT_PROPERTY_SERVICE_RECORD:
+			if (hal_cb != adapter_prop_service_record) {
+				tester_test_failed();
+				return;
+			}
+			remove_expected_hal_cb();
+			break;
+		case BT_PROPERTY_ADAPTER_SCAN_MODE:
+			if (hal_cb != adapter_prop_scan_mode) {
+				tester_test_failed();
+				return;
+			}
+			remove_expected_hal_cb();
+			break;
+		case BT_PROPERTY_ADAPTER_BONDED_DEVICES:
+			if (hal_cb != adapter_prop_bonded_devices) {
+				tester_test_failed();
+				return;
+			}
+			remove_expected_hal_cb();
+			break;
+		case BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT:
+			if (hal_cb != adapter_prop_disc_timeout) {
+				tester_test_failed();
+				return;
+			}
+			remove_expected_hal_cb();
+			break;
+		default:
+			break;
+		}
+	}
+}
+
+static const struct generic_data bluetooth_enable_success_test = {
+	.expected_hal_callbacks = {adapter_props, adapter_state_changed_on,
+							adapter_test_end}
+};
+
 static bt_callbacks_t bt_callbacks = {
 	.size = sizeof(bt_callbacks),
-	.adapter_state_changed_cb = NULL,
-	.adapter_properties_cb = NULL,
+	.adapter_state_changed_cb = adapter_state_changed_cb,
+	.adapter_properties_cb = adapter_properties_cb,
 	.remote_device_properties_cb = NULL,
 	.device_found_cb = NULL,
 	.discovery_state_changed_cb = NULL,
@@ -356,9 +563,22 @@ static void teardown(const void *test_data)
 	if (data->bluetoothd_pid)
 		waitpid(data->bluetoothd_pid, NULL, 0);
 
+	if (data->expected_callbacks)
+		g_slist_free(data->expected_callbacks);
+
 	tester_teardown_complete();
 }
 
+static void test_enable(const void *test_data)
+{
+	struct test_data *data = tester_get_data();
+
+	hal_cb_init(data);
+	mgmt_cb_init(data);
+
+	data->if_bluetooth->enable();
+}
+
 static void controller_setup(const void *test_data)
 {
 	tester_test_passed();
@@ -385,5 +605,8 @@ int main(int argc, char *argv[])
 
 	test_bredrle("Test Init", NULL, setup_base, controller_setup, teardown);
 
+	test_bredrle("Test Enable - Success", &bluetooth_enable_success_test,
+					setup_base, test_enable, teardown);
+
 	return tester_run();
 }
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH v4 7/7] android/tester: Add status check and adapter enable, disable test cases
From: Marcin Kraglak @ 2013-12-11 10:46 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Grzegorz Kolodziejczyk
In-Reply-To: <1386758797-1809-1-git-send-email-marcin.kraglak@tieto.com>

From: Grzegorz Kolodziejczyk <grzegorz.kolodziejczyk@tieto.com>

This adds handling of status check, enabled adapter setup method,
disable and enable fail test case.

---
 android/android-tester.c | 108 ++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 103 insertions(+), 5 deletions(-)

diff --git a/android/android-tester.c b/android/android-tester.c
index 0dc1edf..09c76c9 100644
--- a/android/android-tester.c
+++ b/android/android-tester.c
@@ -46,6 +46,7 @@
 
 enum hal_bluetooth_callbacks_id {
 	adapter_test_end,
+	adapter_test_setup_mode,
 	adapter_state_changed_on,
 	adapter_state_changed_off,
 	adapter_prop_bdaddr,
@@ -59,6 +60,7 @@ enum hal_bluetooth_callbacks_id {
 };
 
 struct generic_data {
+	uint8_t expected_adapter_status;
 	uint32_t expect_settings_set;
 	uint8_t expected_hal_callbacks[];
 };
@@ -78,6 +80,7 @@ struct test_data {
 
 	bool mgmt_settings_set;
 	bool hal_cb_called;
+	bool status_checked;
 
 	GSList *expected_callbacks;
 };
@@ -88,8 +91,13 @@ static void test_update_state(void)
 {
 	struct test_data *data = tester_get_data();
 
-	if (data->mgmt_settings_set && data->hal_cb_called)
-		tester_test_passed();
+	if (!(data->mgmt_settings_set))
+		return;
+	if (!(data->hal_cb_called))
+		return;
+	if (!(data->status_checked))
+		return;
+	tester_test_passed();
 }
 
 static void test_mgmt_settings_set(struct test_data *data)
@@ -143,10 +151,38 @@ static void mgmt_cb_init(struct test_data *data)
 				command_generic_new_settings, NULL, NULL);
 }
 
+static void expected_status_init(struct test_data *data)
+{
+	if (!(data->test_data->expected_adapter_status))
+		data->status_checked = true;
+}
+
+static void init_test_conditions(struct test_data *data)
+{
+	hal_cb_init(data);
+	mgmt_cb_init(data);
+	expected_status_init(data);
+}
+
+static void check_expected_status(uint8_t status)
+{
+	struct test_data *data = tester_get_data();
+
+	if (data->test_data->expected_adapter_status == status)
+		data->status_checked = true;
+	else
+		tester_test_failed();
+
+	test_update_state();
+}
+
 static int get_expected_hal_cb(void)
 {
 	struct test_data *data = tester_get_data();
 
+	if (!(g_slist_length(data->expected_callbacks)))
+		return adapter_test_setup_mode;
+
 	return GPOINTER_TO_INT(data->expected_callbacks->data);
 }
 
@@ -359,13 +395,28 @@ failed:
 
 static void adapter_state_changed_cb(bt_state_t state)
 {
-	switch (get_expected_hal_cb()) {
+	enum hal_bluetooth_callbacks_id hal_cb;
+
+	hal_cb = get_expected_hal_cb();
+
+	switch (hal_cb) {
 	case adapter_state_changed_on:
 		if (state == BT_STATE_ON)
 			remove_expected_hal_cb();
 		else
 			tester_test_failed();
 		break;
+	case adapter_state_changed_off:
+		if (state == BT_STATE_OFF)
+			remove_expected_hal_cb();
+		else
+			tester_test_failed();
+		break;
+	case adapter_test_setup_mode:
+		if (state == BT_STATE_ON)
+			tester_setup_complete();
+		else
+			tester_setup_failed();
 	default:
 		break;
 	}
@@ -379,6 +430,10 @@ static void adapter_properties_cb(bt_status_t status, int num_properties,
 
 	for (i = 0; i < num_properties; i++) {
 		hal_cb = get_expected_hal_cb();
+
+		if (hal_cb == adapter_test_setup_mode)
+			break;
+
 		switch (properties[i].type) {
 		case BT_PROPERTY_BDADDR:
 			if (hal_cb != adapter_prop_bdaddr) {
@@ -454,6 +509,15 @@ static const struct generic_data bluetooth_enable_success_test = {
 							adapter_test_end}
 };
 
+static const struct generic_data bluetooth_enable_done_test = {
+	.expected_hal_callbacks = {adapter_props, adapter_test_end},
+	.expected_adapter_status = BT_STATUS_DONE
+};
+
+static const struct generic_data bluetooth_disable_success_test = {
+	.expected_hal_callbacks = {adapter_state_changed_off, adapter_test_end}
+};
+
 static bt_callbacks_t bt_callbacks = {
 	.size = sizeof(bt_callbacks),
 	.adapter_state_changed_cb = adapter_state_changed_cb,
@@ -551,6 +615,15 @@ static void setup_base(const void *test_data)
 	tester_setup_complete();
 }
 
+static void setup_enabled_adapter(const void *test_data)
+{
+	struct test_data *data = tester_get_data();
+
+	setup(data);
+
+	data->if_bluetooth->enable();
+}
+
 static void teardown(const void *test_data)
 {
 	struct test_data *data = tester_get_data();
@@ -573,12 +646,31 @@ static void test_enable(const void *test_data)
 {
 	struct test_data *data = tester_get_data();
 
-	hal_cb_init(data);
-	mgmt_cb_init(data);
+	init_test_conditions(data);
 
 	data->if_bluetooth->enable();
 }
 
+static void test_enable_done(const void *test_data)
+{
+	struct test_data *data = tester_get_data();
+	bt_status_t adapter_status;
+
+	init_test_conditions(data);
+
+	adapter_status = data->if_bluetooth->enable();
+	check_expected_status(adapter_status);
+}
+
+static void test_disable(const void *test_data)
+{
+	struct test_data *data = tester_get_data();
+
+	init_test_conditions(data);
+
+	data->if_bluetooth->disable();
+}
+
 static void controller_setup(const void *test_data)
 {
 	tester_test_passed();
@@ -608,5 +700,11 @@ int main(int argc, char *argv[])
 	test_bredrle("Test Enable - Success", &bluetooth_enable_success_test,
 					setup_base, test_enable, teardown);
 
+	test_bredrle("Test Enable - Done", &bluetooth_enable_done_test,
+			setup_enabled_adapter, test_enable_done, teardown);
+
+	test_bredrle("Test Disable - Success", &bluetooth_disable_success_test,
+			setup_enabled_adapter, test_disable, teardown);
+
 	return tester_run();
 }
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH BlueZ] build: Add coverage support
From: Luiz Augusto von Dentz @ 2013-12-11 10:55 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

---
 Makefile.am         | 18 ++++++++++++++++++
 acinclude.m4        |  9 +++++++++
 bootstrap-configure |  1 +
 configure.ac        |  2 ++
 4 files changed, 30 insertions(+)

diff --git a/Makefile.am b/Makefile.am
index 15cc149..1a59532 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -331,5 +331,23 @@ lib/bluetooth/%.h: lib/%.h
 	$(AM_V_at)$(MKDIR_P) lib/bluetooth
 	$(AM_V_GEN)$(LN_S) -f "$(abs_top_builddir)"/$< $@
 
+if COVERAGE
+clean-coverage:
+	$(RM) -r coverage
+	@find . -name "*.gcda" -exec $(RM) {} \;
+	$(LCOV) --directory . --zerocounters
+
+check-coverage:
+	@make check
+	$(AM_V_at)$(MKDIR_P) -p coverage
+	$(LCOV) --compat-libtool --directory . --capture --output-file \
+							coverage/check.info
+	@genhtml -o coverage/ coverage/check.info
+
 clean-local:
+	@make clean-coverage
 	$(RM) -r lib/bluetooth
+else
+clean-local:
+	$(RM) -r lib/bluetooth
+endif
diff --git a/acinclude.m4 b/acinclude.m4
index 2065852..e5eb481 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -51,6 +51,15 @@ AC_DEFUN([MISC_FLAGS], [
 			misc_ldflags="$misc_ldflags -pie"
 		fi
 	])
+	AC_ARG_ENABLE(coverage, AC_HELP_STRING([--enable-coverage],
+			[enable coverage flags]), [
+		AC_PATH_PROG([LCOV], [lcov])
+		if (test "$LCOV" && test "${enableval}" = "yes"); then
+			misc_cflags="$misc_cflags -ftest-coverage"
+			misc_cflags="$misc_cflags -fprofile-arcs"
+			misc_ldflags="$misc_ldflags -gcov"
+		fi
+	])
 	AC_SUBST([MISC_CFLAGS], $misc_cflags)
 	AC_SUBST([MISC_LDFLAGS], $misc_ldflags)
 ])
diff --git a/bootstrap-configure b/bootstrap-configure
index c7f08ed..35aa98b 100755
--- a/bootstrap-configure
+++ b/bootstrap-configure
@@ -14,4 +14,5 @@ fi
 		--enable-experimental \
 		--enable-android \
 		--enable-sixaxis \
+		--enable-coverage \
 		--disable-datafiles $*
diff --git a/configure.ac b/configure.ac
index 18d0b55..c55924f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -252,4 +252,6 @@ AC_ARG_ENABLE(android, AC_HELP_STRING([--enable-android],
 					[enable_android=${enableval}])
 AM_CONDITIONAL(ANDROID, test "${enable_android}" = "yes")
 
+AM_CONDITIONAL([COVERAGE], [test "$LCOV"])
+
 AC_OUTPUT(Makefile src/bluetoothd.8 lib/bluez.pc)
-- 
1.8.3.1


^ permalink raw reply related

* Re: [PATCH v4 3/7] android/tester: Start emulator in new process
From: Andrei Emeltchenko @ 2013-12-11 11:10 UTC (permalink / raw)
  To: Marcin Kraglak; +Cc: linux-bluetooth
In-Reply-To: <1386758797-1809-3-git-send-email-marcin.kraglak@tieto.com>

Hi Marcin,

On Wed, Dec 11, 2013 at 11:46:33AM +0100, Marcin Kraglak wrote:
> This is needed because bluetooth->init call is blocking,
> and we have to emulate normal behaviour of android environment.
> That process will exit if it won't receive any message in 2 sec
> or when bluetoothd will exit. Main tester thread will wait for
> this process in teardown method.
> ---
>  android/android-tester.c | 132 ++++++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 131 insertions(+), 1 deletion(-)
> 
> diff --git a/android/android-tester.c b/android/android-tester.c
> index 498da22..ad7aa39 100644
> --- a/android/android-tester.c
> +++ b/android/android-tester.c
> @@ -15,9 +15,15 @@
>   *
>   */
>  
> +#include <stdlib.h>
>  #include <unistd.h>
>  
>  #include <glib.h>
> +#include <sys/socket.h>
> +#include <sys/types.h>
> +#include <sys/wait.h>
> +#include <sys/un.h>
> +#include <libgen.h>
>  
>  #include "lib/bluetooth.h"
>  #include "lib/mgmt.h"
> @@ -29,14 +35,20 @@
>  struct generic_data {
>  };
>  
> +#define WAIT_FOR_SIGNAL_TIME 2 /* in seconds */
> +#define EMULATOR_SIGNAL "emulator_started"
> +
>  struct test_data {
>  	struct mgmt *mgmt;
>  	uint16_t mgmt_index;
>  	struct hciemu *hciemu;
>  	enum hciemu_type hciemu_type;
>  	const struct generic_data *test_data;
> +	pid_t bluetoothd_pid;
>  };
>  
> +static char exec_dir[PATH_MAX + 1];
> +
>  static void read_info_callback(uint8_t status, uint16_t length,
>  					const void *param, void *user_data)
>  {
> @@ -165,13 +177,129 @@ static void test_post_teardown(const void *test_data)
>  	data->hciemu = NULL;
>  }
>  
> +static void bluetoothd_start(int hci_index)
> +{
> +	char prg_name[PATH_MAX + 1];
> +	char index[8];
> +	char *prg_argv[4];
> +
> +	snprintf(prg_name, sizeof(prg_name), "%s/%s", exec_dir, "bluetoothd");
> +	snprintf(index, sizeof(index), "%d", hci_index);
> +
> +	prg_argv[0] = prg_name;
> +	prg_argv[1] = "-i";
> +	prg_argv[2] = index;
> +	prg_argv[3] = NULL;
> +
> +	if (!tester_use_debug())
> +		fclose(stderr);
> +
> +	execve(prg_argv[0], prg_argv, NULL);
> +}
> +
> +static void emulator(int pipe, int hci_index)
> +{
> +	static const char SYSTEM_SOCKET_PATH[] = "\0android_system";
> +	char buf[1024];
> +	struct sockaddr_un addr;
> +	struct timeval tv;
> +	int fd;
> +	ssize_t len;
> +
> +	fd = socket(PF_LOCAL, SOCK_DGRAM | SOCK_CLOEXEC, 0);
> +	if (fd < 0)
> +		goto failed;

return? otherwise you close invalid fd, or check fd in failed 

> +
> +	tv.tv_sec = WAIT_FOR_SIGNAL_TIME;
> +	tv.tv_usec = 0;
> +	setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(tv));
> +
> +	memset(&addr, 0, sizeof(addr));
> +	addr.sun_family = AF_UNIX;
> +	memcpy(addr.sun_path, SYSTEM_SOCKET_PATH, sizeof(SYSTEM_SOCKET_PATH));
> +
> +	if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
> +		perror("Failed to bind system socket");
> +		goto failed;
> +	}
> +
> +	len = write(pipe, EMULATOR_SIGNAL, sizeof(EMULATOR_SIGNAL));
> +

we do not need here empty space

Best regards 
Andrei Emeltchenko 
> +	if (len != sizeof(EMULATOR_SIGNAL))
> +		goto failed;
> +
> +	memset(buf, 0, sizeof(buf));
> +
> +	len = read(fd, buf, sizeof(buf));
> +	if (len <= 0 || (strcmp(buf, "ctl.start=bluetoothd")))
> +		goto failed;
> +
> +	close(pipe);
> +	close(fd);
> +	bluetoothd_start(hci_index);
> +
> +failed:
> +	close(pipe);
> +	close(fd);
> +}
> +
> +static void setup(struct test_data *data)
> +{
> +	int signal_fd[2];
> +	char buf[1024];
> +	pid_t pid;
> +	int len;
> +
> +	if (pipe(signal_fd)) {
> +		tester_setup_failed();
> +		return;
> +	}
> +
> +	pid = fork();
> +
> +	if (pid < 0) {
> +		close(signal_fd[0]);
> +		close(signal_fd[1]);
> +		tester_setup_failed();
> +		return;
> +	}
> +
> +	if (pid == 0) {
> +		if (!tester_use_debug())
> +			fclose(stderr);
> +
> +		close(signal_fd[0]);
> +		emulator(signal_fd[1], data->mgmt_index);
> +		exit(0);
> +	}
> +
> +	close(signal_fd[1]);
> +	data->bluetoothd_pid = pid;
> +
> +	len = read(signal_fd[0], buf, sizeof(buf));
> +	if (len <= 0 || (strcmp(buf, EMULATOR_SIGNAL))) {
> +		close(signal_fd[0]);
> +		tester_setup_failed();
> +		return;
> +	}
> +}
> +
>  static void setup_base(const void *test_data)
>  {
> -	tester_setup_failed();
> +	struct test_data *data = tester_get_data();
> +
> +	setup(data);
> +
> +	tester_setup_complete();
>  }
>  
>  static void teardown(const void *test_data)
>  {
> +	struct test_data *data = tester_get_data();
> +
> +	if (data->bluetoothd_pid)
> +		waitpid(data->bluetoothd_pid, NULL, 0);
> +
>  	tester_teardown_complete();
>  }
>  
> @@ -194,6 +322,8 @@ static void controller_setup(const void *test_data)
>  
>  int main(int argc, char *argv[])
>  {
> +	snprintf(exec_dir, sizeof(exec_dir), "%s", dirname(argv[0]));
> +
>  	tester_init(&argc, &argv);
>  
>  	test_bredrle("Test Init", NULL, setup_base, controller_setup, teardown);
> -- 
> 1.8.3.1
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH v4 1/7] android/tester: Add android-tester
From: Luiz Augusto von Dentz @ 2013-12-11 11:15 UTC (permalink / raw)
  To: Marcin Kraglak; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <1386758797-1809-1-git-send-email-marcin.kraglak@tieto.com>

Hi Marcin,

On Wed, Dec 11, 2013 at 12:46 PM, Marcin Kraglak
<marcin.kraglak@tieto.com> wrote:
> This commit add android-tester.c to tree and Makefile.am.
> This will contain set of unit tests for testing android daemon.
> ---
>  .gitignore               |  1 +
>  android/Makefile.am      |  4 ++++
>  android/android-tester.c | 21 +++++++++++++++++++++
>  3 files changed, 26 insertions(+)
>  create mode 100644 android/android-tester.c
>
> diff --git a/.gitignore b/.gitignore
> index 2d3435a..c570728 100644
> --- a/.gitignore
> +++ b/.gitignore
> @@ -107,3 +107,4 @@ unit/test-*.trs
>  android/system-emulator
>  android/bluetoothd
>  android/haltest
> +android/android-tester
> diff --git a/android/Makefile.am b/android/Makefile.am
> index df04762..0768985 100644
> --- a/android/Makefile.am
> +++ b/android/Makefile.am
> @@ -83,6 +83,10 @@ android_haltest_CFLAGS = $(AM_CFLAGS) -I$(srcdir)/android \
>
>  android_haltest_LDFLAGS = -pthread
>
> +noinst_PROGRAMS += android/android-tester
> +
> +android_android_tester_SOURCES = android/android-tester.c
> +
>  endif
>
>  EXTRA_DIST += android/Android.mk android/hal-ipc-api.txt android/README \
> diff --git a/android/android-tester.c b/android/android-tester.c
> new file mode 100644
> index 0000000..f5c42b0
> --- /dev/null
> +++ b/android/android-tester.c
> @@ -0,0 +1,21 @@
> +/*
> + * Copyright (C) 2013 Intel Corporation
> + *
> + * Licensed under the Apache License, Version 2.0 (the "License");
> + * you may not use this file except in compliance with the License.
> + * You may obtain a copy of the License at
> + *
> + *      http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing, software
> + * distributed under the License is distributed on an "AS IS" BASIS,
> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
> + * See the License for the specific language governing permissions and
> + * limitations under the License.
> + *
> + */
> +
> +int main(int argc, char *argv[])
> +{
> +       return 0;
> +}
> --
> 1.8.3.1

Applied, thanks.


-- 
Luiz Augusto von Dentz

^ permalink raw reply


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