Linux bluetooth development
 help / color / mirror / Atom feed
* [PATCH 1/4] Fix regression with debug via SIGUSR2
From: Gustavo F. Padovan @ 2010-06-04 10:16 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: gustavo

The new dynamic debug feature was not using the SIGUSR2 signal so this was
causing bluetoothd to crash when one tries to toogle debug via SIGUSR2.
This patch brings back such compatibility.
---
 src/log.c  |   31 +++++++++++++++++++++++++++++--
 src/log.h  |    1 +
 src/main.c |    8 ++++++++
 3 files changed, 38 insertions(+), 2 deletions(-)

diff --git a/src/log.c b/src/log.c
index 29e2d7d..4ef178a 100644
--- a/src/log.c
+++ b/src/log.c
@@ -95,9 +95,8 @@ static gboolean is_enabled(struct btd_debug_desc *desc)
         return 0;
 }
 
-void __btd_log_init(const char *debug, int detach)
+static void turn_debug_on(const char *debug)
 {
-	int option = LOG_NDELAY | LOG_PID;
 	struct btd_debug_desc *desc;
 	const char *name = NULL, *file = NULL;
 
@@ -116,6 +115,34 @@ void __btd_log_init(const char *debug, int detach)
 		if (is_enabled(desc))
 			desc->flags |= BTD_DEBUG_FLAG_PRINT;
 	}
+}
+
+static void turn_debug_off()
+{
+	struct btd_debug_desc *desc;
+
+	for (desc = __start___debug; desc < __stop___debug; desc++) {
+		if (is_enabled(desc))
+			desc->flags &= ~BTD_DEBUG_FLAG_PRINT;
+	}
+
+	g_strfreev(enabled);
+	enabled = NULL;
+}
+
+void __btd_toogle_debug()
+{
+	if (enabled == NULL)
+		turn_debug_on("*");
+	else
+		turn_debug_off();
+}
+
+void __btd_log_init(const char *debug, int detach)
+{
+	int option = LOG_NDELAY | LOG_PID;
+
+	turn_debug_on(debug);
 
 	if (!detach)
 		option |= LOG_PERROR;
diff --git a/src/log.h b/src/log.h
index 9af51e7..8c1b937 100644
--- a/src/log.h
+++ b/src/log.h
@@ -30,6 +30,7 @@ void debug(const char *format, ...) __attribute__((format(printf, 1, 2)));
 
 void __btd_log_init(const char *debug, int detach);
 void __btd_log_cleanup(void);
+void __btd_toogle_debug();
 
 struct btd_debug_desc {
         const char *name;
diff --git a/src/main.c b/src/main.c
index 3118a34..d6559b5 100644
--- a/src/main.c
+++ b/src/main.c
@@ -288,6 +288,11 @@ static void sig_term(int sig)
 	g_main_loop_quit(event_loop);
 }
 
+static void sig_debug(int sig)
+{
+	__btd_toogle_debug();
+}
+
 static gchar *option_debug = NULL;
 static gboolean option_detach = TRUE;
 static gboolean option_udev = FALSE;
@@ -406,6 +411,9 @@ int main(int argc, char *argv[])
 	sigaction(SIGTERM, &sa, NULL);
 	sigaction(SIGINT,  &sa, NULL);
 
+	sa.sa_handler = sig_debug;
+	sigaction(SIGUSR2, &sa, NULL);
+
 	sa.sa_handler = SIG_IGN;
 	sigaction(SIGPIPE, &sa, NULL);
 
-- 
1.7.1


^ permalink raw reply related

* Re: [PATCH] gateway_server_remove should unref audio_adapter
From: Zhu Yanhai @ 2010-06-04  8:40 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <20100604083043.GB2714@jh-x301>

On 06/04/2010 04:30 PM, Johan Hedberg wrote:
> Hi,
>
> On Fri, Jun 04, 2010, Zhu Yanhai wrote:
>> gateway_server_remove should unrefer the adapter, not refer it.
>>
>> Signed-off-by: Zhu Yanhai<yanhai.zhu@linux.intel.com>
>
> We don't use Signed-off-by in userspace BlueZ. I fixed it manually for
> you this time. Also try to start the summary line with "Fix ..." for any
> bugfixes (take a look at the upstream git how I changed it). With those
> commit message changes the patch has now been pushed upstream.
>
> Johan
>

Thank you Johan! I promise I will follow these next time :)

Regards,
Zhu Yanhai

^ permalink raw reply

* Re: [PATCH] gateway_server_remove should unref audio_adapter
From: Johan Hedberg @ 2010-06-04  8:30 UTC (permalink / raw)
  To: Zhu Yanhai; +Cc: linux-bluetooth
In-Reply-To: <1275639598-22048-1-git-send-email-yanhai.zhu@linux.intel.com>

Hi,

On Fri, Jun 04, 2010, Zhu Yanhai wrote:
> gateway_server_remove should unrefer the adapter, not refer it.
> 
> Signed-off-by: Zhu Yanhai <yanhai.zhu@linux.intel.com>

We don't use Signed-off-by in userspace BlueZ. I fixed it manually for
you this time. Also try to start the summary line with "Fix ..." for any
bugfixes (take a look at the upstream git how I changed it). With those
commit message changes the patch has now been pushed upstream.

Johan

^ permalink raw reply

* [PATCH 32/32] Add support for mcl reconnections
From: Jose Antonio Santos Cadenas @ 2010-06-04  8:30 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Jose Antonio Santos Cadenas
In-Reply-To: <1275640225-4186-32-git-send-email-santoscadenas@gmail.com>

---
 health/hdp.c |   20 ++++++++++++--------
 1 files changed, 12 insertions(+), 8 deletions(-)

diff --git a/health/hdp.c b/health/hdp.c
index 6a73e05..8a6a0d4 100644
--- a/health/hdp.c
+++ b/health/hdp.c
@@ -56,6 +56,7 @@ struct hdp_connection_cb {
 	struct hdp_instance	*hdpi;
 	uint32_t		rem_id;
 	DBusMessage		*msg;
+	struct hdp_link		*hdpl;
 };
 
 static struct hdp_adapter *find_adapter(GSList *list,
@@ -554,11 +555,15 @@ static void hdp_mcl_connect_cb(struct mcap_mcl *mcl, GError *err, void *data)
 	if (err)
 		goto fail;
 
-	hdpl = create_health_link(hdpi, mcl, &gerr);
-	if (gerr)
-		goto fail;
+	if (cb_data->hdpl)
+		hdpl = cb_data->hdpl;
+	else {
+		hdpl = create_health_link(hdpi, mcl, &gerr);
+		if (gerr)
+			goto fail;
+		hdpi->hlink = g_slist_prepend(hdpi->hlink, hdpl);
+	}
 
-	hdpi->hlink = g_slist_prepend(hdpi->hlink, hdpl);
 	reply = g_dbus_create_reply(msg, DBUS_TYPE_OBJECT_PATH, &hdpl->path,
 							DBUS_TYPE_INVALID);
 	g_dbus_send_message(device->conn, reply);
@@ -664,10 +669,7 @@ static DBusMessage *hdp_connect(DBusConnection *conn,
 	hdpi = l->data;
 	hdpl = get_health_link(hdpi, device);
 	if (hdpl) {
-		if (hdpl->closed) {
-			DBG("Need a reconection");
-			/* TODO: Reconnect */;
-		} else
+		if (!hdpl->closed)
 			return g_dbus_create_reply(msg, DBUS_TYPE_OBJECT_PATH,
 						&hdpl->path, DBUS_TYPE_INVALID);
 	}
@@ -677,6 +679,8 @@ static DBusMessage *hdp_connect(DBusConnection *conn,
 	cb_data->hdpi = hdpi;
 	cb_data->rem_id = rid;
 	cb_data->msg = dbus_message_ref(msg);
+	/* Used for reconnections */
+	cb_data->hdpl = hdpl;
 
 	adapter = device->hdp_adapter->btd_adapter;
 	adapter_get_address(adapter, &src);
-- 
1.6.3.3


^ permalink raw reply related

* [PATCH 31/32] Send MCL disconnect callback to agents
From: Jose Antonio Santos Cadenas @ 2010-06-04  8:30 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: José Antonio Santos Cadenas
In-Reply-To: <1275640225-4186-31-git-send-email-santoscadenas@gmail.com>

From: José Antonio Santos Cadenas <santoscadenas@gmail.com>

Whenever a MCL is discoinnected we shall notify to agents using
D-Bus callback.
---
 health/hdp.c |   82 +++++++++++++++++++++++++++++++++++++--------------------
 1 files changed, 53 insertions(+), 29 deletions(-)

diff --git a/health/hdp.c b/health/hdp.c
index 1fc1cb9..6a73e05 100644
--- a/health/hdp.c
+++ b/health/hdp.c
@@ -393,10 +393,46 @@ static uint8_t hdp_mcap_mdl_reconn_req_cb(struct mcap_mdl *mdl, void *data)
 	return MCAP_REQUEST_NOT_SUPPORTED;
 }
 
+static void health_link_free(struct hdp_link *hdpl)
+{
+	/*TODO: Release structures related with Data Channels */
+
+	if (hdpl->mcl) {
+		mcap_close_mcl(hdpl->mcl, FALSE);
+		mcap_mcl_unref(hdpl->mcl);
+	}
+
+	if (hdpl->path)
+		g_free(hdpl->path);
+
+	if (hdpl->ndc)
+		g_free(hdpl->ndc);
+
+	g_free(hdpl);
+}
+
+static gboolean agent_mcl_disconnect_msg(struct hdp_link *hdpl)
+{
+	struct hdp_instance *hdpi = hdpl->hdpi;
+	DBusMessage* message;
+
+	message = dbus_message_new_method_call(hdpi->aname, hdpi->apath,
+					HEALTH_AGENT, "LinkDisconnected");
+	if (!message) {
+		error("Couldn't allocate D-Bus message");
+		return FALSE;
+	}
+
+	dbus_message_append_args(message, DBUS_TYPE_OBJECT_PATH, &hdpl->path,
+							DBUS_TYPE_INVALID);
+	return g_dbus_send_message(hdpi->adapter->conn, message);
+}
+
 static uint8_t hdp_mcap_mdl_conn_req_cb(struct mcap_mcl *mcl, uint8_t mdepid,
 				uint16_t mdlid, uint8_t *conf, void *data)
 {
 	struct hdp_link *hdpl = data;
+	struct hdp_instance *hdpi;
 	struct hdp_supp_fts *f;
 	struct hdp_dc *dc;
 	uint8_t new_conf;
@@ -418,7 +454,7 @@ static uint8_t hdp_mcap_mdl_conn_req_cb(struct mcap_mcl *mcl, uint8_t mdepid,
 				new_conf = HDP_RELIABLE_DC;
 			break;
 		case HDP_STREAMING_DC:
-			if (g_slist_length(hdpl->channels) == 0)
+			if (!hdpl->channels)
 				return MCAP_CONFIGURATION_REJECTED;
 		case HDP_RELIABLE_DC:
 			if (f->role == HDP_SOURCE)
@@ -427,13 +463,16 @@ static uint8_t hdp_mcap_mdl_conn_req_cb(struct mcap_mcl *mcl, uint8_t mdepid,
 			break;
 		default:
 			/* Special case defined in HDP spec 3.4. When an invalid
-			 * configuration is received we need close the MCL when
+			 * configuration is received we shall close the MCL when
 			 * we are still processing the callback. When MCL is
 			 * closed in a callback the returned value won't be
 			 * proccesed in MCAP */
-			/* TODO: Send MCL disconnection to agent */
-			g_dbus_unregister_interface(hdpl->hdpi->adapter->conn,
-						hdpl->path, HEALTH_LINK);
+			hdpi = hdpl->hdpi;
+			hdpi->hlink = g_slist_remove(hdpi->hlink, hdpl);
+			agent_mcl_disconnect_msg(hdpl);
+			if (!g_dbus_unregister_interface(hdpi->adapter->conn,
+						hdpl->path, HEALTH_LINK))
+				health_link_free(hdpl);
 			return MCAP_CONFIGURATION_REJECTED; /* not processed */
 	}
 	*conf = new_conf;
@@ -447,25 +486,6 @@ static uint8_t hdp_mcap_mdl_conn_req_cb(struct mcap_mcl *mcl, uint8_t mdepid,
 	return MCAP_SUCCESS;
 }
 
-static void health_link_free(struct hdp_link *hdpl)
-{
-	/*TODO: Release structures related with Data Channels */
-
-	if (hdpl->mcl) {
-		mcap_close_mcl(hdpl->mcl, FALSE);
-		mcap_mcl_unref(hdpl->mcl);
-	}
-
-	if (hdpl->path)
-		g_free(hdpl->path);
-
-	if (hdpl->ndc)
-		g_free(hdpl->ndc);
-
-	hdpl->hdpi->hlink = g_slist_remove(hdpl->hdpi->hlink, hdpl);
-	g_free(hdpl);
-}
-
 static void health_link_path_unregister(void *data)
 {
 	struct hdp_link *hdpl = data;
@@ -696,8 +716,11 @@ static DBusMessage *hdp_disconnect(DBusConnection *conn,
 	if (cache) {
 		mcap_close_mcl(hdpl->mcl, cache);
 		hdpl->closed = TRUE;
-	} else
-		g_dbus_unregister_interface(conn, hdpl->path, HEALTH_LINK);
+	} else {
+		hdpl->hdpi->hlink = g_slist_remove(hdpl->hdpi->hlink, hdpl);
+		if (!g_dbus_unregister_interface(conn, hdpl->path, HEALTH_LINK))
+			health_link_free(hdpl);
+	}
 
 	return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
 }
@@ -788,7 +811,6 @@ static void mcl_connected(struct mcap_mcl *mcl, gpointer data)
 	}
 	error("D-Bus send failed");
 	health_link_free(hdpl);
-	dbus_message_unref(message);
 }
 
 static void mcl_reconnected(struct mcap_mcl *mcl, gpointer data)
@@ -837,8 +859,10 @@ static void mcl_uncached(struct mcap_mcl *mcl, gpointer data)
 	hdpl = l->data;
 
 	hdpi->hlink = g_slist_remove(hdpi->hlink, hdpl);
-	g_dbus_unregister_interface(hdpi->adapter->conn, hdpl->path,
-								HEALTH_LINK);
+	agent_mcl_disconnect_msg(hdpl);
+	if (!g_dbus_unregister_interface(hdpi->adapter->conn, hdpl->path,
+								HEALTH_LINK))
+		health_link_free(hdpl);
 }
 
 static DBusMessage *hdp_create_instance(DBusConnection *conn,
-- 
1.6.3.3


^ permalink raw reply related

* [PATCH 30/32] Add a test that creates a simple health agent
From: Jose Antonio Santos Cadenas @ 2010-06-04  8:30 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Jose Antonio Santos Cadenas
In-Reply-To: <1275640225-4186-30-git-send-email-santoscadenas@gmail.com>

---
 test/test-health |   61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 61 insertions(+), 0 deletions(-)
 create mode 100755 test/test-health

diff --git a/test/test-health b/test/test-health
new file mode 100755
index 0000000..2129923
--- /dev/null
+++ b/test/test-health
@@ -0,0 +1,61 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+import dbus
+import dbus.service
+import gobject
+from dbus.mainloop.glib import DBusGMainLoop
+
+agent_iface = 'org.bluez.HealthAgent'
+obj_path = "/org/bluez/test/health/agent"
+
+DBusGMainLoop(set_as_default=True)
+loop = gobject.MainLoop()
+
+bus = dbus.SystemBus()
+manager = dbus.Interface(bus.get_object("org.bluez", "/"),
+						"org.bluez.Manager")
+
+hdp = dbus.Interface(bus.get_object("org.bluez", manager.DefaultAdapter()),
+						"org.bluez.HealthAdapter")
+
+class HDP(dbus.service.Object):
+	def __init__(self, bus, obj_path):
+		self.bus = bus
+		dbus.service.Object.__init__(self, self.bus, obj_path)
+	@dbus.service.method(agent_iface, in_signature='o', out_signature='',
+							sender_keyword='sender')
+	def LinkConnected(self, path, sender=None):
+		print "Connected new link %s: (sender %s)" % (path, sender)
+	@dbus.service.method(agent_iface, in_signature='o', out_signature='',
+							sender_keyword='sender')
+	def LinkDisconnected(self, path, sender=None):
+		print "Link %s: disconnected (sender: %s)" % (path, sender)
+
+session_id = hdp.CreateInstance(dbus.ObjectPath(obj_path),
+	{"data_spec": dbus.Byte(1, variant_level=1),
+        "end_points":dbus.Array([{ "role": dbus.String("sink", variant_level=1),
+			 "specs": dbus.Array([{
+				"data_type":
+					dbus.UInt16(4100, variant_level =1),
+				"description":
+					dbus.String("Oximeter",
+							variant_level = 1),
+				},{
+				"data_type":
+					dbus.UInt16(4103, variant_level =1),
+				"description":
+					dbus.String("Blood pressure",
+							variant_level = 1),
+				}
+				], variant_level=1),
+			},
+	], variant_level=1)})
+
+hdp_obj = HDP(bus, obj_path);
+
+try:
+	print "Waiting for connections, push Ctrl+C to stop"
+	loop.run()
+except:
+	print "Loop interrupted, closing session"
-- 
1.6.3.3


^ permalink raw reply related

* [PATCH 29/32] Call the agent when a new Health Link is created
From: Jose Antonio Santos Cadenas @ 2010-06-04  8:30 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Jose Antonio Santos Cadenas
In-Reply-To: <1275640225-4186-29-git-send-email-santoscadenas@gmail.com>

---
 health/hdp.c       |   27 ++++++++++++++++++++++++---
 src/bluetooth.conf |    1 +
 2 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/health/hdp.c b/health/hdp.c
index 58d0394..1fc1cb9 100644
--- a/health/hdp.c
+++ b/health/hdp.c
@@ -760,14 +760,35 @@ static void mcl_connected(struct mcap_mcl *mcl, gpointer data)
 {
 	struct hdp_instance *hdpi = data;
 	struct hdp_link *hdpl;
+	DBusMessage* message;
 	GError *err = NULL;
 
 	DBG("mcl_connected");
+
+	message = dbus_message_new_method_call(hdpi->aname, hdpi->apath,
+						HEALTH_AGENT, "LinkConnected");
+	if (!message) {
+		error("Couldn't allocate D-Bus message");
+		return;
+	}
+
 	hdpl = create_health_link(hdpi, mcl, &err);
-	if (err)
+	if (err) {
+		dbus_message_unref(message);
 		return;
-	/* TODO: Send the notification to the Agent */
-	hdpi->hlink = g_slist_prepend(hdpi->hlink, hdpl);
+	}
+
+	dbus_message_append_args(message,
+				DBUS_TYPE_OBJECT_PATH, &hdpl->path,
+				DBUS_TYPE_INVALID);
+
+	if (g_dbus_send_message(hdpi->adapter->conn, message)) {
+		hdpi->hlink = g_slist_prepend(hdpi->hlink, hdpl);
+		return;
+	}
+	error("D-Bus send failed");
+	health_link_free(hdpl);
+	dbus_message_unref(message);
 }
 
 static void mcl_reconnected(struct mcap_mcl *mcl, gpointer data)
diff --git a/src/bluetooth.conf b/src/bluetooth.conf
index 56e7a83..4471da5 100644
--- a/src/bluetooth.conf
+++ b/src/bluetooth.conf
@@ -12,6 +12,7 @@
     <allow send_destination="org.bluez"/>
     <allow send_interface="org.bluez.Agent"/>
     <allow send_interface="org.bluez.HandsfreeAgent"/>
+    <allow send_interface="org.bluez.HealthAgent"/>
   </policy>
 
   <policy at_console="true">
-- 
1.6.3.3


^ permalink raw reply related

* [PATCH 28/32] Changed HEALTH_MANAGER_INTERFACE to HEALTH_MANAGER
From: Jose Antonio Santos Cadenas @ 2010-06-04  8:30 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Jose Antonio Santos Cadenas
In-Reply-To: <1275640225-4186-28-git-send-email-santoscadenas@gmail.com>

---
 health/hdp.c       |    6 +++---
 health/hdp_types.h |    7 ++++---
 2 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/health/hdp.c b/health/hdp.c
index bb03ffa..58d0394 100644
--- a/health/hdp.c
+++ b/health/hdp.c
@@ -964,11 +964,11 @@ int hdp_adapter_register(DBusConnection *conn, struct btd_adapter *btd_adapter)
 	adapter = g_new0(struct hdp_adapter, 1);
 
 	DBG("HDP init");
-	if (!g_dbus_register_interface(conn, path, HEALTH_MANAGER_INTERFACE,
+	if (!g_dbus_register_interface(conn, path, HEALTH_MANAGER,
 					hdp_methods, NULL, NULL,
 					adapter, hdp_path_unregister)) {
 		error("Failed to register %s interface to %s",
-						HEALTH_MANAGER_INTERFACE, path);
+						HEALTH_MANAGER, path);
 		g_free(adapter);
 		return -1;
 	}
@@ -988,7 +988,7 @@ void hdp_adapter_unregister(struct btd_adapter *btd_adapter)
 
 	g_dbus_unregister_interface(adapter->conn,
 			adapter_get_path(btd_adapter),
-			HEALTH_MANAGER_INTERFACE);
+			HEALTH_MANAGER);
 	dbus_connection_unref(adapter->conn);
 	btd_adapter_unref(adapter->btd_adapter);
 	adapters = g_slist_remove(adapters, adapter);
diff --git a/health/hdp_types.h b/health/hdp_types.h
index abbfbf3..aff116e 100644
--- a/health/hdp_types.h
+++ b/health/hdp_types.h
@@ -42,9 +42,10 @@
 
 #define HDP_ERROR		g_quark_from_static_string("hdp-error-quark")
 
-#define HEALTH_MANAGER_INTERFACE	"org.bluez.HealthAdapter"
-#define HEALTH_DEVICE			"org.bluez.HealthDevice"
-#define HEALTH_LINK			"org.bluez.HealthLink"
+#define HEALTH_MANAGER		"org.bluez.HealthAdapter"
+#define HEALTH_DEVICE		"org.bluez.HealthDevice"
+#define HEALTH_LINK		"org.bluez.HealthLink"
+#define HEALTH_AGENT		"org.bluez.HealthAgent"
 
 #define HDP_NO_PREFERENCE_DC	0x00
 #define HDP_RELIABLE_DC		0x01
-- 
1.6.3.3


^ permalink raw reply related

* [PATCH 27/32] Change function name when retreiving remote SDP records
From: Jose Antonio Santos Cadenas @ 2010-06-04  8:30 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Jose Antonio Santos Cadenas
In-Reply-To: <1275640225-4186-27-git-send-email-santoscadenas@gmail.com>

---
 health/hdp.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/health/hdp.c b/health/hdp.c
index a480b8e..bb03ffa 100644
--- a/health/hdp.c
+++ b/health/hdp.c
@@ -266,7 +266,7 @@ static void fill_up_health_instances(DBusMessageIter *dict, gpointer data)
 	}
 }
 
-static void sink_health_instances(sdp_list_t *recs, int err, gpointer user_data)
+static void health_records_found(sdp_list_t *recs, int err, gpointer user_data)
 {
 	struct instances_aux *cb_data = user_data;
 	DBusMessage *msg = cb_data->msg;
@@ -314,7 +314,7 @@ static DBusMessage *get_health_instances(DBusConnection *conn,
 
 
 	bt_string2uuid(&uuid, HDP_UUID);
-	if (bt_search_service(&src, &dst, &uuid, sink_health_instances,
+	if (bt_search_service(&src, &dst, &uuid, health_records_found,
 						cb_data, NULL) == 0)
 		return NULL;
 
-- 
1.6.3.3


^ permalink raw reply related

* [PATCH 26/32] Implement connect data channel callback
From: Jose Antonio Santos Cadenas @ 2010-06-04  8:30 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Jose Antonio Santos Cadenas
In-Reply-To: <1275640225-4186-26-git-send-email-santoscadenas@gmail.com>

---
 health/hdp.c       |   68 +++++++++++++++++++++++++++++++++++++++++++++++----
 health/hdp_types.h |    5 ++++
 2 files changed, 67 insertions(+), 6 deletions(-)

diff --git a/health/hdp.c b/health/hdp.c
index f29a1c5..a480b8e 100644
--- a/health/hdp.c
+++ b/health/hdp.c
@@ -107,6 +107,13 @@ static struct hdp_link *find_health_link(struct hdp_adapter *adapter,
 	return NULL;
 }
 
+static int hdp_supp_fts_mdepcmp(gconstpointer ft, gconstpointer mdepid)
+{
+	const struct hdp_supp_fts *fts = ft;
+
+	return bcmp(&fts->mdepid, mdepid, sizeof(uint8_t));
+}
+
 static int hdp_instance_idcmp(gconstpointer instance, gconstpointer p)
 {
 	const struct hdp_instance *hdpi = instance;
@@ -379,19 +386,65 @@ static void hdp_mcap_mdl_closed_cb(struct mcap_mdl *mdl, void *data)
 	DBG("TODO: Incomplete callback, mdl closed");
 }
 
-static uint8_t hdp_mcap_mdl_conn_req_cb(struct mcap_mdl *mdl, void *data)
+static uint8_t hdp_mcap_mdl_reconn_req_cb(struct mcap_mdl *mdl, void *data)
 {
 	/* struct hdp_link *hdpl = data; */
 	DBG("TODO: Incomplete callback, mdl connection request");
 	return MCAP_REQUEST_NOT_SUPPORTED;
 }
 
-static uint8_t hdp_mcap_mdl_reconn_req_cb(struct mcap_mcl *mcl,
-					  uint8_t mdepid, uint16_t mdlid,
-					  uint8_t *conf, void *data)
+static uint8_t hdp_mcap_mdl_conn_req_cb(struct mcap_mcl *mcl, uint8_t mdepid,
+				uint16_t mdlid, uint8_t *conf, void *data)
 {
-	DBG("TODO: Incomplete callback, mdl reconnection request");
-	return MCAP_REQUEST_NOT_SUPPORTED;
+	struct hdp_link *hdpl = data;
+	struct hdp_supp_fts *f;
+	struct hdp_dc *dc;
+	uint8_t new_conf;
+	GSList *l;
+
+	l = g_slist_find_custom(hdpl->hdpi->config->supp_fts, &mdepid,
+							hdp_supp_fts_mdepcmp);
+	if (!l)
+		return MCAP_INVALID_MDEP;
+	f = l->data;
+
+	/* Check if is the first dc if so,
+	 * only reliable configuration is allowed */
+	switch(*conf) {
+		case HDP_NO_PREFERENCE_DC:
+			if (f->role == HDP_SINK)
+				return MCAP_CONFIGURATION_REJECTED;
+			else
+				new_conf = HDP_RELIABLE_DC;
+			break;
+		case HDP_STREAMING_DC:
+			if (g_slist_length(hdpl->channels) == 0)
+				return MCAP_CONFIGURATION_REJECTED;
+		case HDP_RELIABLE_DC:
+			if (f->role == HDP_SOURCE)
+				return MCAP_CONFIGURATION_REJECTED;
+			new_conf = *conf;
+			break;
+		default:
+			/* Special case defined in HDP spec 3.4. When an invalid
+			 * configuration is received we need close the MCL when
+			 * we are still processing the callback. When MCL is
+			 * closed in a callback the returned value won't be
+			 * proccesed in MCAP */
+			/* TODO: Send MCL disconnection to agent */
+			g_dbus_unregister_interface(hdpl->hdpi->adapter->conn,
+						hdpl->path, HEALTH_LINK);
+			return MCAP_CONFIGURATION_REJECTED; /* not processed */
+	}
+	*conf = new_conf;
+
+	dc = g_new0(struct hdp_dc, 1);
+	dc->hdpl = hdpl;
+	dc->conf = *conf;
+	dc->mdlid = mdlid;
+
+	hdpl->ndc = dc;
+	return MCAP_SUCCESS;
 }
 
 static void health_link_free(struct hdp_link *hdpl)
@@ -406,6 +459,9 @@ static void health_link_free(struct hdp_link *hdpl)
 	if (hdpl->path)
 		g_free(hdpl->path);
 
+	if (hdpl->ndc)
+		g_free(hdpl->ndc);
+
 	hdpl->hdpi->hlink = g_slist_remove(hdpl->hdpi->hlink, hdpl);
 	g_free(hdpl);
 }
diff --git a/health/hdp_types.h b/health/hdp_types.h
index 6d41e2b..abbfbf3 100644
--- a/health/hdp_types.h
+++ b/health/hdp_types.h
@@ -46,6 +46,10 @@
 #define HEALTH_DEVICE			"org.bluez.HealthDevice"
 #define HEALTH_LINK			"org.bluez.HealthLink"
 
+#define HDP_NO_PREFERENCE_DC	0x00
+#define HDP_RELIABLE_DC		0x01
+#define HDP_STREAMING_DC	0x02
+
 typedef enum {
 	HDP_DIC_PARSE_ERROR,
 	HDP_DIC_ENTRY_PARSE_ERROR,
@@ -113,6 +117,7 @@ struct hdp_link {
 	GSList			*channels;	/* Data channels */
 	char			*path;		/* HDP link path */
 	uint32_t		id;		/* Health link id */
+	struct hdp_dc		*ndc;		/* Data channel negotiated */
 };
 
 struct hdp_dc {
-- 
1.6.3.3


^ permalink raw reply related

* [PATCH 25/32] Create new structure to manage data channels in HDP
From: Jose Antonio Santos Cadenas @ 2010-06-04  8:30 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Jose Antonio Santos Cadenas
In-Reply-To: <1275640225-4186-25-git-send-email-santoscadenas@gmail.com>

---
 health/hdp_types.h |    7 +++++++
 1 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/health/hdp_types.h b/health/hdp_types.h
index 5db8e0d..6d41e2b 100644
--- a/health/hdp_types.h
+++ b/health/hdp_types.h
@@ -115,6 +115,13 @@ struct hdp_link {
 	uint32_t		id;		/* Health link id */
 };
 
+struct hdp_dc {
+	struct hdp_link		*hdpl;		/* Health link */
+	struct mcap_mdl		*mdl;		/* MCAP MDL structure */
+	uint8_t			conf;		/* Requested conf */
+	uint16_t		mdlid;		/* MDL id */
+};
+
 struct hdp_device {
 	DBusConnection		*conn;		/* For name listener handling */
 	struct btd_device	*dev;		/* Device reference */
-- 
1.6.3.3


^ permalink raw reply related

* [PATCH 24/32] Disconnect health link petition
From: Jose Antonio Santos Cadenas @ 2010-06-04  8:30 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Jose Antonio Santos Cadenas
In-Reply-To: <1275640225-4186-24-git-send-email-santoscadenas@gmail.com>

---
 health/hdp.c |   28 +++++++++++++++-------------
 1 files changed, 15 insertions(+), 13 deletions(-)

diff --git a/health/hdp.c b/health/hdp.c
index ed26fe5..f29a1c5 100644
--- a/health/hdp.c
+++ b/health/hdp.c
@@ -401,13 +401,10 @@ static void health_link_free(struct hdp_link *hdpl)
 	if (hdpl->mcl) {
 		mcap_close_mcl(hdpl->mcl, FALSE);
 		mcap_mcl_unref(hdpl->mcl);
-		hdpl->mcl = NULL;
 	}
 
-	if (hdpl->path) {
+	if (hdpl->path)
 		g_free(hdpl->path);
-		hdpl->path = NULL;
-	}
 
 	hdpl->hdpi->hlink = g_slist_remove(hdpl->hdpi->hlink, hdpl);
 	g_free(hdpl);
@@ -623,32 +620,37 @@ static DBusMessage *hdp_disconnect(DBusConnection *conn,
 					DBusMessage *msg, void *user_data)
 {
 	struct hdp_device *device = user_data;
-	struct hdp_link *hlink;
+	struct hdp_link *hdpl;
 	const char *path;
-	const gboolean *del;
+	gboolean cache;
 
 	if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
-							DBUS_TYPE_BOOLEAN, &del,
-							DBUS_TYPE_INVALID)){
+						DBUS_TYPE_BOOLEAN, &cache,
+						DBUS_TYPE_INVALID)){
 		return g_dbus_create_error(msg,
 					ERROR_INTERFACE ".InvalidArguments",
 					"Invalid arguments in method call");
 	}
 
-	hlink = find_health_link(device->hdp_adapter, path);
-	if (!hlink)
+	hdpl = find_health_link(device->hdp_adapter, path);
+	if (!hdpl)
 		return g_dbus_create_error(msg, ERROR_INTERFACE ".HealthError",
 						"Health link does not found");
 
-	return g_dbus_create_error(msg, ERROR_INTERFACE ".HealthError",
-							"Not yet implemented");
+	if (cache) {
+		mcap_close_mcl(hdpl->mcl, cache);
+		hdpl->closed = TRUE;
+	} else
+		g_dbus_unregister_interface(conn, hdpl->path, HEALTH_LINK);
+
+	return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
 }
 
 static GDBusMethodTable device_methods[] = {
 	{ "GetHealthInstances", "", "aa{sv}", get_health_instances,
 						G_DBUS_METHOD_FLAG_ASYNC },
 	{ "Connect", "uu", "o", hdp_connect, G_DBUS_METHOD_FLAG_ASYNC },
-	{ "Diconnect", "ob", "", hdp_disconnect },
+	{ "Disconnect", "ob", "", hdp_disconnect },
 	{ NULL }
 };
 
-- 
1.6.3.3


^ permalink raw reply related

* [PATCH 23/32] Avoid multiple links with the same device
From: Jose Antonio Santos Cadenas @ 2010-06-04  8:30 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Jose Antonio Santos Cadenas
In-Reply-To: <1275640225-4186-23-git-send-email-santoscadenas@gmail.com>

---
 health/hdp.c |   42 ++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 40 insertions(+), 2 deletions(-)

diff --git a/health/hdp.c b/health/hdp.c
index d6a8758..ed26fe5 100644
--- a/health/hdp.c
+++ b/health/hdp.c
@@ -117,7 +117,8 @@ static int hdp_instance_idcmp(gconstpointer instance, gconstpointer p)
 	return -1;
 }
 
-static int hdp_link_mcl_cmp(gconstpointer link, gconstpointer mcl){
+static int hdp_link_mcl_cmp(gconstpointer link, gconstpointer mcl)
+{
 	const struct hdp_link *hdpl = link;
 
 	if (hdpl->mcl == mcl)
@@ -125,6 +126,17 @@ static int hdp_link_mcl_cmp(gconstpointer link, gconstpointer mcl){
 	return -1;
 }
 
+static int hdp_link_addr_cmp(gconstpointer link, gconstpointer addr)
+{
+	const struct hdp_link *hdpl = link;
+	const bdaddr_t *dst;
+        bdaddr_t mcl_addr;
+
+	dst = addr;
+	mcl_addr = mcap_mcl_get_addr(hdpl->mcl);
+	return bacmp(addr, &mcl_addr);
+}
+
 static void set_health_link_path(struct hdp_link *hdpl)
 {
 	char path[MAX_PATH_LENGTH + 1];
@@ -534,12 +546,27 @@ fail:
 	g_dbus_send_message(device->conn, reply);
 }
 
+static struct hdp_link *get_health_link(struct hdp_instance *hdpi,
+						struct hdp_device *device)
+{
+	bdaddr_t dst;
+	GSList *l;
+
+	device_get_address(device->dev, &dst);
+	l = g_slist_find_custom(hdpi->hlink, &dst, hdp_link_addr_cmp);
+	if (l)
+		return l->data;
+	return NULL;
+}
+
 static DBusMessage *hdp_connect(DBusConnection *conn,
 					DBusMessage *msg, void *user_data)
 {
 	struct hdp_device *device = user_data;
 	struct hdp_connection_cb *cb_data;
 	struct btd_adapter *adapter;
+	struct hdp_instance *hdpi;
+	struct hdp_link *hdpl;
 	bdaddr_t src, dst;
 	uint32_t lid, rid;
 	uuid_t uuid;
@@ -561,9 +588,20 @@ static DBusMessage *hdp_connect(DBusConnection *conn,
 					   ERROR_INTERFACE ".InvalidArguments",
 					   "Invalid local health instance id");
 
+	hdpi = l->data;
+	hdpl = get_health_link(hdpi, device);
+	if (hdpl) {
+		if (hdpl->closed) {
+			DBG("Need a reconection");
+			/* TODO: Reconnect */;
+		} else
+			return g_dbus_create_reply(msg, DBUS_TYPE_OBJECT_PATH,
+						&hdpl->path, DBUS_TYPE_INVALID);
+	}
+
 	cb_data = g_new0(struct hdp_connection_cb, 1);
 	cb_data->device = device;
-	cb_data->hdpi = l->data;
+	cb_data->hdpi = hdpi;
 	cb_data->rem_id = rid;
 	cb_data->msg = dbus_message_ref(msg);
 
-- 
1.6.3.3


^ permalink raw reply related

* [PATCH 22/32] Initial work for disconnecting health links
From: Jose Antonio Santos Cadenas @ 2010-06-04  8:30 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Jose Antonio Santos Cadenas
In-Reply-To: <1275640225-4186-22-git-send-email-santoscadenas@gmail.com>

---
 health/hdp.c |   45 +++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 45 insertions(+), 0 deletions(-)

diff --git a/health/hdp.c b/health/hdp.c
index 310f6ff..d6a8758 100644
--- a/health/hdp.c
+++ b/health/hdp.c
@@ -88,6 +88,25 @@ static struct hdp_device *find_device(GSList *devices, struct btd_device *dev)
 	return NULL;
 }
 
+static struct hdp_link *find_health_link(struct hdp_adapter *adapter,
+							const char *link_path)
+{
+	struct hdp_instance *hdpi;
+	struct hdp_link *hdpl;
+	GSList *l, *ll;
+
+	for (l = adapter->instances; l; l = l->next) {
+		hdpi = l->data;
+		for (ll = hdpi->hlink; ll; ll = ll->next) {
+			hdpl = ll->data;
+			if (!strcmp(hdpl->path, link_path))
+				return hdpl;
+		}
+	}
+
+	return NULL;
+}
+
 static int hdp_instance_idcmp(gconstpointer instance, gconstpointer p)
 {
 	const struct hdp_instance *hdpi = instance;
@@ -562,10 +581,36 @@ static DBusMessage *hdp_connect(DBusConnection *conn,
 				   "Error getting remote information");
 }
 
+static DBusMessage *hdp_disconnect(DBusConnection *conn,
+					DBusMessage *msg, void *user_data)
+{
+	struct hdp_device *device = user_data;
+	struct hdp_link *hlink;
+	const char *path;
+	const gboolean *del;
+
+	if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
+							DBUS_TYPE_BOOLEAN, &del,
+							DBUS_TYPE_INVALID)){
+		return g_dbus_create_error(msg,
+					ERROR_INTERFACE ".InvalidArguments",
+					"Invalid arguments in method call");
+	}
+
+	hlink = find_health_link(device->hdp_adapter, path);
+	if (!hlink)
+		return g_dbus_create_error(msg, ERROR_INTERFACE ".HealthError",
+						"Health link does not found");
+
+	return g_dbus_create_error(msg, ERROR_INTERFACE ".HealthError",
+							"Not yet implemented");
+}
+
 static GDBusMethodTable device_methods[] = {
 	{ "GetHealthInstances", "", "aa{sv}", get_health_instances,
 						G_DBUS_METHOD_FLAG_ASYNC },
 	{ "Connect", "uu", "o", hdp_connect, G_DBUS_METHOD_FLAG_ASYNC },
+	{ "Diconnect", "ob", "", hdp_disconnect },
 	{ NULL }
 };
 
-- 
1.6.3.3


^ permalink raw reply related

* [PATCH 21/32] Manage mcap disconnections and reconnections
From: Jose Antonio Santos Cadenas @ 2010-06-04  8:30 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Jose Antonio Santos Cadenas
In-Reply-To: <1275640225-4186-21-git-send-email-santoscadenas@gmail.com>

---
 health/hdp.c       |   58 ++++++++++++++++++++++++++++++++++++++++++---------
 health/hdp_types.h |    5 ++++
 health/hdp_util.c  |   19 ++++++++++++----
 3 files changed, 66 insertions(+), 16 deletions(-)

diff --git a/health/hdp.c b/health/hdp.c
index 4ed0150..310f6ff 100644
--- a/health/hdp.c
+++ b/health/hdp.c
@@ -37,10 +37,6 @@
 
 #include "../src/dbus-common.h"
 
-#define HEALTH_MANAGER_INTERFACE	"org.bluez.HealthAdapter"
-#define HEALTH_DEVICE			"org.bluez.HealthDevice"
-#define HEALTH_LINK			"org.bluez.HealthLink"
-
 static GSList *adapters = NULL;
 static GSList *devices = NULL;
 
@@ -102,6 +98,14 @@ static int hdp_instance_idcmp(gconstpointer instance, gconstpointer p)
 	return -1;
 }
 
+static int hdp_link_mcl_cmp(gconstpointer link, gconstpointer mcl){
+	const struct hdp_link *hdpl = link;
+
+	if (hdpl->mcl == mcl)
+		return 0;
+	return -1;
+}
+
 static void set_health_link_path(struct hdp_link *hdpl)
 {
 	char path[MAX_PATH_LENGTH + 1];
@@ -617,7 +621,7 @@ static void mcl_connected(struct mcap_mcl *mcl, gpointer data)
 	struct hdp_link *hdpl;
 	GError *err = NULL;
 
-	DBG("TODO: implement mcl_connected");
+	DBG("mcl_connected");
 	hdpl = create_health_link(hdpi, mcl, &err);
 	if (err)
 		return;
@@ -627,20 +631,52 @@ static void mcl_connected(struct mcap_mcl *mcl, gpointer data)
 
 static void mcl_reconnected(struct mcap_mcl *mcl, gpointer data)
 {
-	/* struct hdp_instance *hdpi = data; */
-	DBG("TODO: implement mcl_reconnected");
+	struct hdp_instance *hdpi = data;
+	struct hdp_link *hdpl;
+	GSList *l;
+
+	DBG("mcl_reconnected");
+	l = g_slist_find_custom(hdpi->hlink, mcl, hdp_link_mcl_cmp);
+	if (l) {
+		hdpl = l->data;
+		hdpl->closed = FALSE;
+		return;
+	}
+
+	mcl_connected(mcl, data);
 }
 
 static void mcl_disconnected(struct mcap_mcl *mcl, gpointer data)
 {
-	/* struct hdp_instance *hdpi = data; */
-	DBG("TODO: implement mcl_disconnected");
+	struct hdp_instance *hdpi = data;
+	struct hdp_link *hdpl;
+	GSList *l;
+
+	DBG("mcl_disconnected");
+	l = g_slist_find_custom(hdpi->hlink, mcl, hdp_link_mcl_cmp);
+	if (!l)
+		return;
+
+	hdpl = l->data;
+	hdpl->closed = TRUE;
 }
 
 static void mcl_uncached(struct mcap_mcl *mcl, gpointer data)
 {
-	/* struct hdp_instance *hdpi = data; */
-	DBG("TODO: implement mcl_uncached");
+	struct hdp_instance *hdpi = data;
+	struct hdp_link *hdpl;
+	GSList *l;
+
+	DBG("mcl_uncached");
+	l = g_slist_find_custom(hdpi->hlink, mcl, hdp_link_mcl_cmp);
+	if (!l)
+		return;
+
+	hdpl = l->data;
+
+	hdpi->hlink = g_slist_remove(hdpi->hlink, hdpl);
+	g_dbus_unregister_interface(hdpi->adapter->conn, hdpl->path,
+								HEALTH_LINK);
 }
 
 static DBusMessage *hdp_create_instance(DBusConnection *conn,
diff --git a/health/hdp_types.h b/health/hdp_types.h
index 79419a1..5db8e0d 100644
--- a/health/hdp_types.h
+++ b/health/hdp_types.h
@@ -42,6 +42,10 @@
 
 #define HDP_ERROR		g_quark_from_static_string("hdp-error-quark")
 
+#define HEALTH_MANAGER_INTERFACE	"org.bluez.HealthAdapter"
+#define HEALTH_DEVICE			"org.bluez.HealthDevice"
+#define HEALTH_LINK			"org.bluez.HealthLink"
+
 typedef enum {
 	HDP_DIC_PARSE_ERROR,
 	HDP_DIC_ENTRY_PARSE_ERROR,
@@ -105,6 +109,7 @@ struct hdp_instance {
 struct hdp_link {
 	struct hdp_instance	*hdpi;		/* HDP session */
 	struct mcap_mcl 	*mcl;		/* MCAP mcl */
+	gboolean		closed;		/* MCL is closed but cached */
 	GSList			*channels;	/* Data channels */
 	char			*path;		/* HDP link path */
 	uint32_t		id;		/* Health link id */
diff --git a/health/hdp_util.c b/health/hdp_util.c
index 2706a74..d09ee6d 100644
--- a/health/hdp_util.c
+++ b/health/hdp_util.c
@@ -109,15 +109,24 @@ static void free_config(struct hdp_config *config)
 	g_free(config);
 }
 
+static void hdp_link_unregister(gpointer link, gpointer data)
+{
+	struct hdp_link *hdpl = link;
+	struct hdp_instance *hdpi = hdpl->hdpi;
+
+	hdpi->hlink = g_slist_remove(hdpi->hlink, hdpl);
+	g_dbus_unregister_interface(hdpi->adapter->conn, hdpl->path,
+								HEALTH_LINK);
+}
+
 void hdp_instance_free(struct hdp_instance *hdpi)
 {
 	DBG("HDP instance %d is deleted", hdpi->id);
 	/* TODO: Complete this part */
-	/*
-	g_slist_foreach(hdpi->devices, hdp_device_unregister, NULL);
-	g_slist_free(hdpi->devices);
-	hdpi->devices = NULL;
-	*/
+
+	g_slist_foreach(hdpi->hlink, hdp_link_unregister, NULL);
+	g_slist_free(hdpi->hlink);
+	hdpi->hlink = NULL;
 
 	if (hdpi->dbus_watcher)
 		g_dbus_remove_watch(hdpi->adapter->conn, hdpi->dbus_watcher);
-- 
1.6.3.3


^ permalink raw reply related

* [PATCH 20/32] Release health link resources
From: Jose Antonio Santos Cadenas @ 2010-06-04  8:30 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Jose Antonio Santos Cadenas
In-Reply-To: <1275640225-4186-20-git-send-email-santoscadenas@gmail.com>

---
 health/hdp.c |   27 ++++++++++++++++++++++++---
 1 files changed, 24 insertions(+), 3 deletions(-)

diff --git a/health/hdp.c b/health/hdp.c
index 234109a..4ed0150 100644
--- a/health/hdp.c
+++ b/health/hdp.c
@@ -359,10 +359,32 @@ static uint8_t hdp_mcap_mdl_reconn_req_cb(struct mcap_mcl *mcl,
 	return MCAP_REQUEST_NOT_SUPPORTED;
 }
 
+static void health_link_free(struct hdp_link *hdpl)
+{
+	/*TODO: Release structures related with Data Channels */
+
+	if (hdpl->mcl) {
+		mcap_close_mcl(hdpl->mcl, FALSE);
+		mcap_mcl_unref(hdpl->mcl);
+		hdpl->mcl = NULL;
+	}
+
+	if (hdpl->path) {
+		g_free(hdpl->path);
+		hdpl->path = NULL;
+	}
+
+	hdpl->hdpi->hlink = g_slist_remove(hdpl->hdpi->hlink, hdpl);
+	g_free(hdpl);
+}
+
 static void health_link_path_unregister(void *data)
 {
-	/* struct hdp_link *hdpl = data */
-	/* TODO: Unregister hdp_link*/
+	struct hdp_link *hdpl = data;
+
+	DBG("Unregistered interface %s on path %s", HEALTH_LINK, hdpl->path);
+
+	health_link_free(hdpl);
 }
 
 static GDBusMethodTable health_link_methods[] = {
@@ -399,7 +421,6 @@ static struct hdp_link *create_health_link(struct hdp_instance *hdpi,
 	g_set_error(err, HDP_ERROR, HDP_UNSPECIFIED_ERROR,
 				"Cant register the health link in the bus");
 
-	/* TODO create a function to free health link correctly */
 	/* MCAP will close the MCL and won't cache it if we didn't
 	* increase the MCL reference counter during the callback. */
 	mcap_mcl_unref(hdpl->mcl);
-- 
1.6.3.3


^ permalink raw reply related

* [PATCH 19/32] Remove hdp_device pointer from health link struct
From: Jose Antonio Santos Cadenas @ 2010-06-04  8:30 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Jose Antonio Santos Cadenas
In-Reply-To: <1275640225-4186-19-git-send-email-santoscadenas@gmail.com>

---
 health/hdp.c       |    6 +++---
 health/hdp_types.h |    1 -
 2 files changed, 3 insertions(+), 4 deletions(-)

diff --git a/health/hdp.c b/health/hdp.c
index eb673bd..234109a 100644
--- a/health/hdp.c
+++ b/health/hdp.c
@@ -391,9 +391,9 @@ static struct hdp_link *create_health_link(struct hdp_instance *hdpi,
 	if (*err)
 		return NULL;
 
-	if (g_dbus_register_interface(hdpl->dev->conn, hdpl->path, HEALTH_LINK,
-					health_link_methods, NULL, NULL,
-					hdpl, health_link_path_unregister))
+	if (g_dbus_register_interface(hdpl->hdpi->adapter->conn, hdpl->path,
+				HEALTH_LINK, health_link_methods,
+				NULL, NULL, hdpl, health_link_path_unregister))
 		return hdpl;
 
 	g_set_error(err, HDP_ERROR, HDP_UNSPECIFIED_ERROR,
diff --git a/health/hdp_types.h b/health/hdp_types.h
index 05bfbfe..79419a1 100644
--- a/health/hdp_types.h
+++ b/health/hdp_types.h
@@ -104,7 +104,6 @@ struct hdp_instance {
 
 struct hdp_link {
 	struct hdp_instance	*hdpi;		/* HDP session */
-	struct hdp_device	*dev;		/* Health Device */
 	struct mcap_mcl 	*mcl;		/* MCAP mcl */
 	GSList			*channels;	/* Data channels */
 	char			*path;		/* HDP link path */
-- 
1.6.3.3


^ permalink raw reply related

* [PATCH 18/32] Unify the creation of health links
From: Jose Antonio Santos Cadenas @ 2010-06-04  8:30 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Jose Antonio Santos Cadenas
In-Reply-To: <1275640225-4186-18-git-send-email-santoscadenas@gmail.com>

---
 health/hdp.c |   82 ++++++++++++++++++++++++++++++++++++---------------------
 1 files changed, 52 insertions(+), 30 deletions(-)

diff --git a/health/hdp.c b/health/hdp.c
index d38aff1..eb673bd 100644
--- a/health/hdp.c
+++ b/health/hdp.c
@@ -369,28 +369,17 @@ static GDBusMethodTable health_link_methods[] = {
 	{ NULL }
 };
 
-static void hdp_mcl_connect_cb(struct mcap_mcl *mcl, GError *err, void *data)
+static struct hdp_link *create_health_link(struct hdp_instance *hdpi,
+					struct mcap_mcl *mcl, GError **err)
 {
-	struct hdp_connection_cb *cb_data = data;
-	struct hdp_device *device = cb_data->device;
-	struct hdp_instance *hdpi = cb_data->hdpi;
-	DBusMessage *msg = cb_data->msg;
-	struct hdp_link *hdpl = NULL;
-	GError *cberr = NULL;
-	DBusMessage *reply;
-
-	g_free(cb_data);
-
-	if (err)
-		goto fail;
+	struct hdp_link *hdpl;
 
 	hdpl = g_new0(struct hdp_link, 1);
 	hdpl->hdpi = hdpi;
-	hdpl->dev = device;
 	hdpl->mcl = mcap_mcl_ref(mcl);
 	set_health_link_path(hdpl);
 
-	mcap_mcl_set_cb(mcl, &cberr, hdpl,
+	mcap_mcl_set_cb(mcl, err, hdpl,
 		MCAP_MDL_CB_CONNECTED, hdp_mcap_mdl_connected_cb,
 		MCAP_MDL_CB_CLOSED, hdp_mcap_mdl_closed_cb,
 		MCAP_MDL_CB_DELETED, hdp_mcap_mdl_deleted_cb,
@@ -399,16 +388,46 @@ static void hdp_mcl_connect_cb(struct mcap_mcl *mcl, GError *err, void *data)
 		MCAP_MDL_CB_REMOTE_RECONN_REQ, hdp_mcap_mdl_reconn_req_cb,
 		MCAP_MDL_CB_INVALID);
 
-	if (cberr)
-		goto fail;
+	if (*err)
+		return NULL;
 
-	if (!g_dbus_register_interface(hdpl->dev->conn, hdpl->path, HEALTH_LINK,
+	if (g_dbus_register_interface(hdpl->dev->conn, hdpl->path, HEALTH_LINK,
 					health_link_methods, NULL, NULL,
-					hdpl, health_link_path_unregister)) {
-		error("D-Bus failed to register %s interface to %s",
+					hdpl, health_link_path_unregister))
+		return hdpl;
+
+	g_set_error(err, HDP_ERROR, HDP_UNSPECIFIED_ERROR,
+				"Cant register the health link in the bus");
+
+	/* TODO create a function to free health link correctly */
+	/* MCAP will close the MCL and won't cache it if we didn't
+	* increase the MCL reference counter during the callback. */
+	mcap_mcl_unref(hdpl->mcl);
+	g_free(hdpl->path);
+	g_free(hdpl);
+	error("D-Bus failed to register %s interface to %s",
 						HEALTH_LINK, hdpl->path);
+	return NULL;
+}
+
+static void hdp_mcl_connect_cb(struct mcap_mcl *mcl, GError *err, void *data)
+{
+	struct hdp_connection_cb *cb_data = data;
+	struct hdp_device *device = cb_data->device;
+	struct hdp_instance *hdpi = cb_data->hdpi;
+	DBusMessage *msg = cb_data->msg;
+	struct hdp_link *hdpl = NULL;
+	GError *gerr = NULL;
+	DBusMessage *reply;
+
+	g_free(cb_data);
+
+	if (err)
+		goto fail;
+
+	hdpl = create_health_link(hdpi, mcl, &gerr);
+	if (gerr)
 		goto fail;
-	}
 
 	hdpi->hlink = g_slist_prepend(hdpi->hlink, hdpl);
 	reply = g_dbus_create_reply(msg, DBUS_TYPE_OBJECT_PATH, &hdpl->path,
@@ -417,14 +436,9 @@ static void hdp_mcl_connect_cb(struct mcap_mcl *mcl, GError *err, void *data)
 	return;
 fail:
 	reply = g_dbus_create_error(msg, ERROR_INTERFACE ".HdpError",
-					(err ? err->message : cberr->message));
-	if (cberr) {
-		/* MCAP will close the MCL and won't cache it if we didn't
-		* increase the MCL reference counter during the callback. */
-		mcap_mcl_unref(hdpl->mcl);
-		g_free(hdpl->path);
-		g_free(hdpl);
-		g_error_free(cberr);
+					(err ? err->message : gerr->message));
+	if (gerr) {
+		g_error_free(gerr);
 	}
 
 	g_dbus_send_message(device->conn, reply);
@@ -578,8 +592,16 @@ static void client_disconnected(DBusConnection *connection, void *user_data)
 
 static void mcl_connected(struct mcap_mcl *mcl, gpointer data)
 {
-	/* struct hdp_instance *hdpi = data; */
+	struct hdp_instance *hdpi = data;
+	struct hdp_link *hdpl;
+	GError *err = NULL;
+
 	DBG("TODO: implement mcl_connected");
+	hdpl = create_health_link(hdpi, mcl, &err);
+	if (err)
+		return;
+	/* TODO: Send the notification to the Agent */
+	hdpi->hlink = g_slist_prepend(hdpi->hlink, hdpl);
 }
 
 static void mcl_reconnected(struct mcap_mcl *mcl, gpointer data)
-- 
1.6.3.3


^ permalink raw reply related

* [PATCH 17/32] Analize remote record looking for psm
From: Jose Antonio Santos Cadenas @ 2010-06-04  8:30 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Jose Antonio Santos Cadenas
In-Reply-To: <1275640225-4186-17-git-send-email-santoscadenas@gmail.com>

---
 health/hdp.c      |    1 +
 health/hdp_util.c |   52 +++++++++++++++++++++++++++++++++++++---------------
 2 files changed, 38 insertions(+), 15 deletions(-)

diff --git a/health/hdp.c b/health/hdp.c
index 752714a..d38aff1 100644
--- a/health/hdp.c
+++ b/health/hdp.c
@@ -462,6 +462,7 @@ static void connect_health_instance(sdp_list_t *recs, int err, gpointer data)
 		goto fail;
 	}
 
+	info("psm = 0x%x, version = 0x%x", ccpsm, version);
 	device_get_address(device->dev, &dst);
 	mcap_create_mcl(hdpi->mi, &dst, ccpsm, &gerr, hdp_mcl_connect_cb,
 								cb_data);
diff --git a/health/hdp_util.c b/health/hdp_util.c
index a7fc1d5..2706a74 100644
--- a/health/hdp_util.c
+++ b/health/hdp_util.c
@@ -884,29 +884,51 @@ gboolean hdp_get_data_exchange_spec(const sdp_record_t *rec, guint8 *val)
 	return TRUE;
 }
 
+static gboolean get_prot_desc_entry(sdp_data_t *entry, int type, guint16 *val)
+{
+	sdp_data_t *iter;
+	int proto;
+
+	if (!entry || (entry->dtd != SDP_SEQ8))
+		return FALSE;
+
+	iter = entry->val.dataseq;
+	if (!(iter->dtd & SDP_UUID_UNSPEC))
+		return FALSE;
+
+	proto = sdp_uuid_to_proto(&iter->val.uuid);
+	if (proto != type)
+		return FALSE;
+
+	iter = iter->next;
+	if (iter->dtd != SDP_UINT16)
+		return FALSE;
+	if (val) {
+		*val = iter->val.uint16;
+	}
+	return TRUE;
+}
+
 gboolean hdp_get_prot_desc_list(const sdp_record_t *rec, guint16 *psm,
 							guint16 *version)
 {
-	if (!(psm || version))
+	sdp_data_t *pdl, *p0, *p1;
+
+	if (!psm && !version)
 		return TRUE;
 
-	/* TODO:
-	sdp_data_t *pdl, *l;
+	pdl = sdp_data_get(rec, SDP_ATTR_PROTO_DESC_LIST);
+	if (pdl->dtd != SDP_SEQ8)
+		return FALSE;
+
+	p0 = pdl->val.dataseq;
 
-	exspec = sdp_data_get(rec, SDP_ATTR_PROTO_DESC_LIST);
-	if (exspec->dtd != SDP_SEQ8)
+	if (!get_prot_desc_entry(p0, L2CAP_UUID, psm))
+		return FALSE;
+	p1 = p0->next;
+	if (!get_prot_desc_entry(p1, MCAP_CTRL_UUID, version))
 		return FALSE;
 
-	for (l = pdl->val.dataseq; l; l = l->next) {
-		if (l->dtd != SDP_SEQ8)
-			continue;
-		epl = get_feature(epl, l->val.dataseq);
-	}
-	*/
-	if (psm)
-		*psm = 0x1001;
-	if (version)
-		*version = 0x0100;
 	return TRUE;
 }
 
-- 
1.6.3.3


^ permalink raw reply related

* [PATCH 16/32] Register Health link int the bus when MCL is connected
From: Jose Antonio Santos Cadenas @ 2010-06-04  8:30 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Jose Antonio Santos Cadenas
In-Reply-To: <1275640225-4186-16-git-send-email-santoscadenas@gmail.com>

---
 health/hdp.c       |   64 ++++++++++++++++++++++++++++++++++++++++++++++-----
 health/hdp_types.h |   12 +++++++++-
 2 files changed, 68 insertions(+), 8 deletions(-)

diff --git a/health/hdp.c b/health/hdp.c
index f5dc107..752714a 100644
--- a/health/hdp.c
+++ b/health/hdp.c
@@ -37,8 +37,9 @@
 
 #include "../src/dbus-common.h"
 
-#define HEALTH_MANAGER_INTERFACE       "org.bluez.HealthAdapter"
-#define HEALTH_DEVICE                  "org.bluez.HealthDevice"
+#define HEALTH_MANAGER_INTERFACE	"org.bluez.HealthAdapter"
+#define HEALTH_DEVICE			"org.bluez.HealthDevice"
+#define HEALTH_LINK			"org.bluez.HealthLink"
 
 static GSList *adapters = NULL;
 static GSList *devices = NULL;
@@ -101,6 +102,18 @@ static int hdp_instance_idcmp(gconstpointer instance, gconstpointer p)
 	return -1;
 }
 
+static void set_health_link_path(struct hdp_link *hdpl)
+{
+	char path[MAX_PATH_LENGTH + 1];
+
+	hdpl->id = hdpl->hdpi->hlc++;
+	snprintf(path, MAX_PATH_LENGTH, "%s/health_link_%d_%d",
+		adapter_get_path(hdpl->hdpi->adapter->btd_adapter),
+		hdpl->hdpi->id, hdpl->id);
+
+	hdpl->path = g_strdup(path);
+}
+
 static void fill_up_one_spec(DBusMessageIter *dict, gpointer data)
 {
 	struct hdp_feature *feature = data;
@@ -346,12 +359,23 @@ static uint8_t hdp_mcap_mdl_reconn_req_cb(struct mcap_mcl *mcl,
 	return MCAP_REQUEST_NOT_SUPPORTED;
 }
 
+static void health_link_path_unregister(void *data)
+{
+	/* struct hdp_link *hdpl = data */
+	/* TODO: Unregister hdp_link*/
+}
+
+static GDBusMethodTable health_link_methods[] = {
+	{ NULL }
+};
+
 static void hdp_mcl_connect_cb(struct mcap_mcl *mcl, GError *err, void *data)
 {
 	struct hdp_connection_cb *cb_data = data;
 	struct hdp_device *device = cb_data->device;
-	/* struct hdp_instance *hdpi = cb_data->hdpi; */
+	struct hdp_instance *hdpi = cb_data->hdpi;
 	DBusMessage *msg = cb_data->msg;
+	struct hdp_link *hdpl = NULL;
 	GError *cberr = NULL;
 	DBusMessage *reply;
 
@@ -360,8 +384,13 @@ static void hdp_mcl_connect_cb(struct mcap_mcl *mcl, GError *err, void *data)
 	if (err)
 		goto fail;
 
-	/* Create and Register HealthLink interface */
-	mcap_mcl_set_cb(mcl, &cberr, NULL /*health_link*/,
+	hdpl = g_new0(struct hdp_link, 1);
+	hdpl->hdpi = hdpi;
+	hdpl->dev = device;
+	hdpl->mcl = mcap_mcl_ref(mcl);
+	set_health_link_path(hdpl);
+
+	mcap_mcl_set_cb(mcl, &cberr, hdpl,
 		MCAP_MDL_CB_CONNECTED, hdp_mcap_mdl_connected_cb,
 		MCAP_MDL_CB_CLOSED, hdp_mcap_mdl_closed_cb,
 		MCAP_MDL_CB_DELETED, hdp_mcap_mdl_deleted_cb,
@@ -369,14 +398,35 @@ static void hdp_mcl_connect_cb(struct mcap_mcl *mcl, GError *err, void *data)
 		MCAP_MDL_CB_REMOTE_CONN_REQ, hdp_mcap_mdl_conn_req_cb,
 		MCAP_MDL_CB_REMOTE_RECONN_REQ, hdp_mcap_mdl_reconn_req_cb,
 		MCAP_MDL_CB_INVALID);
+
 	if (cberr)
 		goto fail;
+
+	if (!g_dbus_register_interface(hdpl->dev->conn, hdpl->path, HEALTH_LINK,
+					health_link_methods, NULL, NULL,
+					hdpl, health_link_path_unregister)) {
+		error("D-Bus failed to register %s interface to %s",
+						HEALTH_LINK, hdpl->path);
+		goto fail;
+	}
+
+	hdpi->hlink = g_slist_prepend(hdpi->hlink, hdpl);
+	reply = g_dbus_create_reply(msg, DBUS_TYPE_OBJECT_PATH, &hdpl->path,
+							DBUS_TYPE_INVALID);
+	g_dbus_send_message(device->conn, reply);
 	return;
 fail:
 	reply = g_dbus_create_error(msg, ERROR_INTERFACE ".HdpError",
 					(err ? err->message : cberr->message));
-	if (!cberr)
+	if (cberr) {
+		/* MCAP will close the MCL and won't cache it if we didn't
+		* increase the MCL reference counter during the callback. */
+		mcap_mcl_unref(hdpl->mcl);
+		g_free(hdpl->path);
+		g_free(hdpl);
 		g_error_free(cberr);
+	}
+
 	g_dbus_send_message(device->conn, reply);
 }
 
@@ -421,8 +471,8 @@ static void connect_health_instance(sdp_list_t *recs, int err, gpointer data)
 	reply = g_dbus_create_error(msg, ERROR_INTERFACE ".HealthError",
 			"Error getting remote protocol descriptor list");
 fail:
-	g_dbus_send_message(device->conn, reply);
 	g_free(cb_data);
+	g_dbus_send_message(device->conn, reply);
 }
 
 static DBusMessage *hdp_connect(DBusConnection *conn,
diff --git a/health/hdp_types.h b/health/hdp_types.h
index 3bab4ea..05bfbfe 100644
--- a/health/hdp_types.h
+++ b/health/hdp_types.h
@@ -99,10 +99,20 @@ struct hdp_instance {
 	struct hdp_config	*config;	/* Configuration */
 	uint32_t		sdp_handler;	/* SDP record handler */
 	guint			dbus_watcher;	/* Client D-Bus conn watcher */
+	uint16_t		hlc;		/* Health link id. counter */
+};
+
+struct hdp_link {
+	struct hdp_instance	*hdpi;		/* HDP session */
+	struct hdp_device	*dev;		/* Health Device */
+	struct mcap_mcl 	*mcl;		/* MCAP mcl */
+	GSList			*channels;	/* Data channels */
+	char			*path;		/* HDP link path */
+	uint32_t		id;		/* Health link id */
 };
 
 struct hdp_device {
-	DBusConnection		*conn;		/* for name listener handling */
+	DBusConnection		*conn;		/* For name listener handling */
 	struct btd_device	*dev;		/* Device reference */
 	struct hdp_adapter	*hdp_adapter;	/* hdp_adapater */
 };
-- 
1.6.3.3


^ permalink raw reply related

* [PATCH 15/32] Implement connect MCL callback in health instances connection
From: Jose Antonio Santos Cadenas @ 2010-06-04  8:30 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Jose Antonio Santos Cadenas
In-Reply-To: <1275640225-4186-15-git-send-email-santoscadenas@gmail.com>

---
 health/hdp.c |   76 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 73 insertions(+), 3 deletions(-)

diff --git a/health/hdp.c b/health/hdp.c
index e57d64c..f5dc107 100644
--- a/health/hdp.c
+++ b/health/hdp.c
@@ -33,6 +33,8 @@
 
 #include "glib-helper.h"
 
+#include "../mcap/mcap.h"
+
 #include "../src/dbus-common.h"
 
 #define HEALTH_MANAGER_INTERFACE       "org.bluez.HealthAdapter"
@@ -305,12 +307,77 @@ static sdp_record_t *get_record(sdp_list_t *recs, uint32_t handle)
 	return NULL;
 }
 
+static void hdp_mcap_mdl_connected_cb(struct mcap_mdl *mdl, void *data)
+{
+	/* struct hdp_link *hdpl = data; */
+	DBG("TODO: Incomplete callback, mdl connected");
+}
+
+static void hdp_mcap_mdl_deleted_cb(struct mcap_mdl *mdl, void *data)
+{
+	/* struct hdp_link *hdpl = data; */
+	DBG("TODO: Incomplete callback, mdl deleted");
+}
+
+static void hdp_mcap_mdl_aborted_cb(struct mcap_mdl *mdl, void *data)
+{
+	/* struct hdp_link *hdpl = data; */
+	DBG("TODO: Incomplete callback, mdl aborted");
+}
+
+static void hdp_mcap_mdl_closed_cb(struct mcap_mdl *mdl, void *data)
+{
+	/* struct hdp_link *hdpl = data; */
+	DBG("TODO: Incomplete callback, mdl closed");
+}
+
+static uint8_t hdp_mcap_mdl_conn_req_cb(struct mcap_mdl *mdl, void *data)
+{
+	/* struct hdp_link *hdpl = data; */
+	DBG("TODO: Incomplete callback, mdl connection request");
+	return MCAP_REQUEST_NOT_SUPPORTED;
+}
+
+static uint8_t hdp_mcap_mdl_reconn_req_cb(struct mcap_mcl *mcl,
+					  uint8_t mdepid, uint16_t mdlid,
+					  uint8_t *conf, void *data)
+{
+	DBG("TODO: Incomplete callback, mdl reconnection request");
+	return MCAP_REQUEST_NOT_SUPPORTED;
+}
+
 static void hdp_mcl_connect_cb(struct mcap_mcl *mcl, GError *err, void *data)
 {
 	struct hdp_connection_cb *cb_data = data;
+	struct hdp_device *device = cb_data->device;
+	/* struct hdp_instance *hdpi = cb_data->hdpi; */
+	DBusMessage *msg = cb_data->msg;
+	GError *cberr = NULL;
+	DBusMessage *reply;
 
-	/* TODO */
 	g_free(cb_data);
+
+	if (err)
+		goto fail;
+
+	/* Create and Register HealthLink interface */
+	mcap_mcl_set_cb(mcl, &cberr, NULL /*health_link*/,
+		MCAP_MDL_CB_CONNECTED, hdp_mcap_mdl_connected_cb,
+		MCAP_MDL_CB_CLOSED, hdp_mcap_mdl_closed_cb,
+		MCAP_MDL_CB_DELETED, hdp_mcap_mdl_deleted_cb,
+		MCAP_MDL_CB_ABORTED, hdp_mcap_mdl_aborted_cb,
+		MCAP_MDL_CB_REMOTE_CONN_REQ, hdp_mcap_mdl_conn_req_cb,
+		MCAP_MDL_CB_REMOTE_RECONN_REQ, hdp_mcap_mdl_reconn_req_cb,
+		MCAP_MDL_CB_INVALID);
+	if (cberr)
+		goto fail;
+	return;
+fail:
+	reply = g_dbus_create_error(msg, ERROR_INTERFACE ".HdpError",
+					(err ? err->message : cberr->message));
+	if (!cberr)
+		g_error_free(cberr);
+	g_dbus_send_message(device->conn, reply);
 }
 
 static void connect_health_instance(sdp_list_t *recs, int err, gpointer data)
@@ -383,7 +450,7 @@ static DBusMessage *hdp_connect(DBusConnection *conn,
 	if (!l)
 		return g_dbus_create_error(msg,
 					   ERROR_INTERFACE ".InvalidArguments",
-					   "Invalid local instance id");
+					   "Invalid local health instance id");
 
 	cb_data = g_new0(struct hdp_connection_cb, 1);
 	cb_data->device = device;
@@ -400,6 +467,7 @@ static DBusMessage *hdp_connect(DBusConnection *conn,
 							cb_data, NULL) == 0)
 		return NULL;
 
+	g_free(cb_data);
 	return g_dbus_create_error(msg, ERROR_INTERFACE ".HealthError",
 				   "Error getting remote information");
 }
@@ -499,6 +567,7 @@ static DBusMessage *hdp_create_instance(DBusConnection *conn,
 		return g_dbus_create_error(msg,
 					ERROR_INTERFACE ".InvalidArguments",
 					"Invalid arguments in method call");
+
 	dbus_message_iter_get_basic(&iter, &path);
 	dbus_message_iter_next(&iter);
 	config = hdp_get_config(&iter, &err);
@@ -509,6 +578,7 @@ static DBusMessage *hdp_create_instance(DBusConnection *conn,
 		g_error_free(err);
 		return reply;
 	}
+
 	name = dbus_message_get_sender(msg);
 	if (!name) {
 		return g_dbus_create_error(msg,
@@ -552,7 +622,7 @@ static DBusMessage *hdp_create_instance(DBusConnection *conn,
 							DBUS_TYPE_INVALID);
 error:
 	reply = g_dbus_create_error(msg,ERROR_INTERFACE ".HealthError",
-					err->message);
+								err->message);
 	g_error_free(err);
 	hdp_instance_free(hdpi);
 	return reply;
-- 
1.6.3.3


^ permalink raw reply related

* [PATCH 14/32] Manage mcap instances
From: Jose Antonio Santos Cadenas @ 2010-06-04  8:30 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Jose Antonio Santos Cadenas
In-Reply-To: <1275640225-4186-14-git-send-email-santoscadenas@gmail.com>

---
 health/hdp.c      |   73 ++++++++++++++++++++++++++++++++++++++++------------
 health/hdp_util.c |    3 +-
 2 files changed, 58 insertions(+), 18 deletions(-)

diff --git a/health/hdp.c b/health/hdp.c
index b9f637e..e57d64c 100644
--- a/health/hdp.c
+++ b/health/hdp.c
@@ -457,6 +457,30 @@ static void client_disconnected(DBusConnection *connection, void *user_data)
 	hdp_instance_free(hdpi);
 }
 
+static void mcl_connected(struct mcap_mcl *mcl, gpointer data)
+{
+	/* struct hdp_instance *hdpi = data; */
+	DBG("TODO: implement mcl_connected");
+}
+
+static void mcl_reconnected(struct mcap_mcl *mcl, gpointer data)
+{
+	/* struct hdp_instance *hdpi = data; */
+	DBG("TODO: implement mcl_reconnected");
+}
+
+static void mcl_disconnected(struct mcap_mcl *mcl, gpointer data)
+{
+	/* struct hdp_instance *hdpi = data; */
+	DBG("TODO: implement mcl_disconnected");
+}
+
+static void mcl_uncached(struct mcap_mcl *mcl, gpointer data)
+{
+	/* struct hdp_instance *hdpi = data; */
+	DBG("TODO: implement mcl_uncached");
+}
+
 static DBusMessage *hdp_create_instance(DBusConnection *conn,
 				      DBusMessage *msg, void *user_data)
 {
@@ -472,17 +496,24 @@ static DBusMessage *hdp_create_instance(DBusConnection *conn,
 	dbus_message_iter_init(msg, &iter);
 	ctype = dbus_message_iter_get_arg_type(&iter);
 	if (ctype != DBUS_TYPE_OBJECT_PATH)
-		goto error;
+		return g_dbus_create_error(msg,
+					ERROR_INTERFACE ".InvalidArguments",
+					"Invalid arguments in method call");
 	dbus_message_iter_get_basic(&iter, &path);
 	dbus_message_iter_next(&iter);
 	config = hdp_get_config(&iter, &err);
-	if (err)
-		goto error;
+	if (err) {
+		reply = g_dbus_create_error(msg,
+					ERROR_INTERFACE ".InvalidArguments",
+					"Invalid arguments: %s", err->message);
+		g_error_free(err);
+		return reply;
+	}
 	name = dbus_message_get_sender(msg);
 	if (!name) {
-		g_set_error(&err, HDP_ERROR, HDP_UNSPECIFIED_ERROR,
-						"Can't get sender name");
-		goto error;
+		return g_dbus_create_error(msg,
+					ERROR_INTERFACE ".InvalidArguments",
+					"Can't get sender name");
 	}
 
 	hdpi = g_new0(struct hdp_instance, 1);
@@ -494,7 +525,20 @@ static DBusMessage *hdp_create_instance(DBusConnection *conn,
 	hdpi->dbus_watcher = g_dbus_add_disconnect_watch(adapter->conn, name,
 					client_disconnected, hdpi, NULL);
 
-	/* TODO: Create mcap instance */
+	hdpi->mi = mcap_create_instance(adapter->btd_adapter, BT_IO_SEC_MEDIUM,
+					0, 0, &err, mcl_connected,
+					mcl_reconnected, mcl_disconnected,
+					mcl_uncached, hdpi);
+	if (err)
+		goto error;
+
+	hdpi->ccpsm = mcap_get_ctrl_psm(hdpi->mi, &err);
+	if (err)
+		goto error;
+
+	hdpi->dcpsm = mcap_get_data_psm(hdpi->mi, &err);
+	if (err)
+		goto error;
 
 	if (!hdp_register_sdp_record(hdpi)) {
 		hdp_instance_free(hdpi);
@@ -503,19 +547,14 @@ static DBusMessage *hdp_create_instance(DBusConnection *conn,
 	}
 
 	adapter->instances = g_slist_prepend(adapter->instances, hdpi);
-	info("HDP instance created with path %d", hdpi->id);
+	DBG("HDP instance created with id %d", hdpi->id);
 	return g_dbus_create_reply(msg, DBUS_TYPE_UINT32, &hdpi->id,
 							DBUS_TYPE_INVALID);
 error:
-	if (err) {
-		reply = g_dbus_create_error(msg,
-					ERROR_INTERFACE ".InvalidArguments",
-					"Invalid arguments: %s", err->message);
-		g_error_free(err);
-	} else
-		reply = g_dbus_create_error(msg,
-					ERROR_INTERFACE ".InvalidArguments",
-					"Invalid arguments in method call");
+	reply = g_dbus_create_error(msg,ERROR_INTERFACE ".HealthError",
+					err->message);
+	g_error_free(err);
+	hdp_instance_free(hdpi);
 	return reply;
 }
 
diff --git a/health/hdp_util.c b/health/hdp_util.c
index 066147a..a7fc1d5 100644
--- a/health/hdp_util.c
+++ b/health/hdp_util.c
@@ -123,7 +123,8 @@ void hdp_instance_free(struct hdp_instance *hdpi)
 		g_dbus_remove_watch(hdpi->adapter->conn, hdpi->dbus_watcher);
 	if (hdpi->sdp_handler)
 		remove_record_from_server(hdpi->sdp_handler);
-	/* TODO: stop mcap instance */
+	if (hdpi->mi)
+		mcap_release_instance(hdpi->mi);
 	if (hdpi->apath)
 		g_free(hdpi->apath);
 	if (hdpi->aname)
-- 
1.6.3.3


^ permalink raw reply related

* [PATCH 13/32] Implement connection of health instances
From: Jose Antonio Santos Cadenas @ 2010-06-04  8:30 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Jose Antonio Santos Cadenas
In-Reply-To: <1275640225-4186-13-git-send-email-santoscadenas@gmail.com>

---
 health/hdp.c      |  100 ++++++++++++++++++++++++++++++++++++++++++++++++++---
 health/hdp_util.c |   26 ++++++++++++++
 health/hdp_util.h |    2 +
 3 files changed, 123 insertions(+), 5 deletions(-)

diff --git a/health/hdp.c b/health/hdp.c
index 840af0f..b9f637e 100644
--- a/health/hdp.c
+++ b/health/hdp.c
@@ -52,6 +52,13 @@ struct health_instances_aux {
 	GSList		*end_points;
 };
 
+struct hdp_connection_cb {
+	struct hdp_device	*device;
+	struct hdp_instance	*hdpi;
+	uint32_t		rem_id;
+	DBusMessage		*msg;
+};
+
 static struct hdp_adapter *find_adapter(GSList *list,
 					struct btd_adapter *btd_adapter)
 {
@@ -240,7 +247,7 @@ static DBusMessage *get_health_instances(DBusConnection *conn,
 	bdaddr_t src, dst;
 	uuid_t uuid;
 
-	adapter = device_get_adapter(device->dev);
+	adapter = device->hdp_adapter->btd_adapter;
 	adapter_get_address(adapter, &src);
 	device_get_address(device->dev, &dst);
 
@@ -284,12 +291,82 @@ static void dev_path_unregister(void *data)
 	health_device_free(device);
 }
 
+static sdp_record_t *get_record(sdp_list_t *recs, uint32_t handle)
+{
+	sdp_record_t *rec;
+	sdp_list_t *l;
+
+	for (l = recs; l; l = l->next) {
+		rec = l->data;
+		if (rec->handle == handle)
+			return rec;
+	}
+
+	return NULL;
+}
+
+static void hdp_mcl_connect_cb(struct mcap_mcl *mcl, GError *err, void *data)
+{
+	struct hdp_connection_cb *cb_data = data;
+
+	/* TODO */
+	g_free(cb_data);
+}
+
+static void connect_health_instance(sdp_list_t *recs, int err, gpointer data)
+{
+	struct hdp_connection_cb *cb_data = data;
+	struct hdp_device *device = cb_data->device;
+	struct hdp_instance *hdpi = cb_data->hdpi;
+	GError *gerr = NULL;
+	uint32_t rid = cb_data->rem_id;
+	DBusMessage *msg = cb_data->msg;
+	DBusMessage *reply;
+	sdp_record_t *rec;
+	guint16 ccpsm, version;
+	bdaddr_t dst;
+
+	if (err != 0) {
+		reply = g_dbus_create_error(msg, ERROR_INTERFACE ".HealthError",
+				"Error getting remote information");
+		goto fail;
+	}
+
+	rec = get_record(recs, rid);
+	if (!rec) {
+		reply = g_dbus_create_error(msg, ERROR_INTERFACE ".HealthError",
+				"Error getting remote information");
+		goto fail;
+	}
+
+	if (!hdp_get_prot_desc_list(rec, &ccpsm, &version)) {
+		reply = g_dbus_create_error(msg, ERROR_INTERFACE ".HealthError",
+			"Error getting remote protocol descriptor list");
+		goto fail;
+	}
+
+	device_get_address(device->dev, &dst);
+	mcap_create_mcl(hdpi->mi, &dst, ccpsm, &gerr, hdp_mcl_connect_cb,
+								cb_data);
+	if (!gerr)
+		return;
+
+	reply = g_dbus_create_error(msg, ERROR_INTERFACE ".HealthError",
+			"Error getting remote protocol descriptor list");
+fail:
+	g_dbus_send_message(device->conn, reply);
+	g_free(cb_data);
+}
+
 static DBusMessage *hdp_connect(DBusConnection *conn,
 					DBusMessage *msg, void *user_data)
 {
 	struct hdp_device *device = user_data;
-	struct hdp_instance *hdpi;
+	struct hdp_connection_cb *cb_data;
+	struct btd_adapter *adapter;
+	bdaddr_t src, dst;
 	uint32_t lid, rid;
+	uuid_t uuid;
 	GSList *l;
 
 	if (!dbus_message_get_args(msg, NULL,
@@ -307,11 +384,24 @@ static DBusMessage *hdp_connect(DBusConnection *conn,
 		return g_dbus_create_error(msg,
 					   ERROR_INTERFACE ".InvalidArguments",
 					   "Invalid local instance id");
-	hdpi = l->data;
 
+	cb_data = g_new0(struct hdp_connection_cb, 1);
+	cb_data->device = device;
+	cb_data->hdpi = l->data;
+	cb_data->rem_id = rid;
+	cb_data->msg = dbus_message_ref(msg);
 
-	return g_dbus_create_error(msg, ERROR_INTERFACE ".HdpError",
-					"Function is not yet implemented");
+	adapter = device->hdp_adapter->btd_adapter;
+	adapter_get_address(adapter, &src);
+	device_get_address(device->dev, &dst);
+
+	bt_string2uuid(&uuid, HDP_UUID);
+	if (bt_search_service(&src, &dst, &uuid, connect_health_instance,
+							cb_data, NULL) == 0)
+		return NULL;
+
+	return g_dbus_create_error(msg, ERROR_INTERFACE ".HealthError",
+				   "Error getting remote information");
 }
 
 static GDBusMethodTable device_methods[] = {
diff --git a/health/hdp_util.c b/health/hdp_util.c
index 921a1e1..066147a 100644
--- a/health/hdp_util.c
+++ b/health/hdp_util.c
@@ -883,6 +883,32 @@ gboolean hdp_get_data_exchange_spec(const sdp_record_t *rec, guint8 *val)
 	return TRUE;
 }
 
+gboolean hdp_get_prot_desc_list(const sdp_record_t *rec, guint16 *psm,
+							guint16 *version)
+{
+	if (!(psm || version))
+		return TRUE;
+
+	/* TODO:
+	sdp_data_t *pdl, *l;
+
+	exspec = sdp_data_get(rec, SDP_ATTR_PROTO_DESC_LIST);
+	if (exspec->dtd != SDP_SEQ8)
+		return FALSE;
+
+	for (l = pdl->val.dataseq; l; l = l->next) {
+		if (l->dtd != SDP_SEQ8)
+			continue;
+		epl = get_feature(epl, l->val.dataseq);
+	}
+	*/
+	if (psm)
+		*psm = 0x1001;
+	if (version)
+		*version = 0x0100;
+	return TRUE;
+}
+
 static gint cmp_feat_mdep(gconstpointer a, gconstpointer b)
 {
 	const struct hdp_supp_fts *fts = a;
diff --git a/health/hdp_util.h b/health/hdp_util.h
index 08e6471..03a7256 100644
--- a/health/hdp_util.h
+++ b/health/hdp_util.h
@@ -37,6 +37,8 @@ typedef void (*hdp_dbus_fill_up)(DBusMessageIter *iter, gpointer data);
 struct hdp_config *hdp_get_config(DBusMessageIter *iter, GError **err);
 gboolean hdp_register_sdp_record(struct hdp_instance *hdps);
 gboolean hdp_get_data_exchange_spec(const sdp_record_t *rec, guint8 *val);
+gboolean hdp_get_prot_desc_list(const sdp_record_t *rec, guint16 *psm,
+							guint16 *version);
 GSList *hdp_get_end_points(const sdp_record_t *rec);
 void hdp_instance_free(struct hdp_instance *hdpi);
 
-- 
1.6.3.3


^ permalink raw reply related

* [PATCH 12/32] Complete the response dictionary in GetHealthInstances response
From: Jose Antonio Santos Cadenas @ 2010-06-04  8:30 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Jose Antonio Santos Cadenas
In-Reply-To: <1275640225-4186-12-git-send-email-santoscadenas@gmail.com>

---
 health/hdp.c      |  169 ++++++++++++++++++++++++++++++++++-------------------
 health/hdp_util.c |   56 +++++++++++++++++-
 health/hdp_util.h |   12 ++++
 3 files changed, 175 insertions(+), 62 deletions(-)

diff --git a/health/hdp.c b/health/hdp.c
index 8bb6057..840af0f 100644
--- a/health/hdp.c
+++ b/health/hdp.c
@@ -46,6 +46,12 @@ struct instances_aux {
 	DBusMessage		*msg;
 };
 
+struct health_instances_aux {
+	guint32		handler;
+	guint8		data_spec;
+	GSList		*end_points;
+};
+
 static struct hdp_adapter *find_adapter(GSList *list,
 					struct btd_adapter *btd_adapter)
 {
@@ -86,41 +92,114 @@ static int hdp_instance_idcmp(gconstpointer instance, gconstpointer p)
 	return -1;
 }
 
-static void append_dict_features(DBusMessageIter *iter, GSList *end_points)
+static void fill_up_one_spec(DBusMessageIter *dict, gpointer data)
 {
-	DBusMessageIter entry, array;
-
-	dbus_message_iter_open_container(iter, DBUS_TYPE_DICT_ENTRY,
-								NULL, &entry);
-	dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, "end_points");
-
-	dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT,
-			DBUS_TYPE_VARIANT_AS_STRING
-			DBUS_TYPE_ARRAY_AS_STRING
-			DBUS_TYPE_ARRAY_AS_STRING
-			DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
-			DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
-			DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &array);
-
-	dbus_message_iter_close_container(&entry, &array);
-	dbus_message_iter_close_container(iter, &entry);
+	struct hdp_feature *feature = data;
+
+	dict_append_entry(dict, "dtype", DBUS_TYPE_UINT16, &feature->dtype);
+	if (feature->dscr)
+		dict_append_entry(dict, "description", DBUS_TYPE_STRING,
+								&feature->dscr);
 }
 
-static void append_array_entry(DBusMessageIter *iter, uint32_t *handler,
-					uint8_t *spec, GSList *end_points)
+static void fill_up_specs(DBusMessageIter *dict, gpointer data)
 {
-	DBusMessageIter dict;
+	GSList *specs = data;
+	GSList *l;
+	struct hdp_feature *feature;
+
 
-	dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
-			DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
-			DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
-			DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
+	for (l = specs; l; l = l->next) {
+		feature = l->data;
 
-	dict_append_entry(&dict, "id", DBUS_TYPE_UINT32, handler);
-	dict_append_entry(&dict, "data_spec", DBUS_TYPE_BYTE, spec);
-	append_dict_features(&dict, end_points);
+		hdp_append_dict(dict, fill_up_one_spec, feature);
+	}
+}
+
+static void fill_up_specs_array(DBusMessageIter *array, gpointer data)
+{
+	hdp_append_array_of_dicts(array, fill_up_specs, data);
+}
 
-	dbus_message_iter_close_container(iter, &dict);
+static void fill_up_one_end_point(DBusMessageIter *dict, gpointer data)
+{
+	struct hdp_supp_fts *fts = data;
+	const char *role;
+
+	if (fts->role == HDP_SOURCE)
+		role = HDP_SOURCE_ROLE_AS_STRING;
+	else if (fts->role == HDP_SINK)
+		role = HDP_SINK_ROLE_AS_STRING;
+
+	dict_append_entry(dict, "mdepid", DBUS_TYPE_BYTE, &fts->mdepid);
+	dict_append_entry(dict, "role", DBUS_TYPE_STRING, &role);
+	hdp_append_variant_array_entry(dict, "specs", fill_up_specs_array,
+								fts->features);
+}
+
+static void fill_up_end_points(DBusMessageIter *dict, gpointer data)
+{
+	GSList *end_points = data;
+	struct hdp_supp_fts *fts;
+	GSList *l;
+
+	for (l = end_points; l; l = l->next) {
+		fts = l->data;
+
+		if (fts->role != HDP_SOURCE && fts->role != HDP_SINK)
+			continue;
+
+		hdp_append_dict(dict, fill_up_one_end_point, fts);
+	}
+}
+
+static void fill_up_end_points_array(DBusMessageIter *iter, gpointer data)
+{
+	hdp_append_array_of_dicts(iter, fill_up_end_points, data);
+}
+
+static void fill_up_instance(DBusMessageIter *entry, gpointer data)
+{
+	struct health_instances_aux *aux = data;
+	guint32 handler = aux->handler;
+	guint8 data_spec = aux->data_spec;
+	GSList *end_points = aux->end_points;
+
+	dict_append_entry(entry, "id", DBUS_TYPE_UINT32, &handler);
+	dict_append_entry(entry, "data_spec", DBUS_TYPE_BYTE, &data_spec);
+	hdp_append_variant_array_entry(entry, "end_points",
+					fill_up_end_points_array, end_points);
+}
+
+static void fill_up_health_instances(DBusMessageIter *dict, gpointer data)
+{
+	sdp_list_t *recs = data;
+	sdp_record_t *rec;
+	sdp_list_t *l;
+	guint8 data_spec;
+	GSList *end_points;
+	struct health_instances_aux *aux;
+
+	for (l = recs; l; l = l->next) {
+		rec = l->data;
+		DBG("Record found 0x%x", rec->handle);
+
+		if (!hdp_get_data_exchange_spec(rec, &data_spec)) {
+			error("Error getting data exchange info");
+			continue;
+		}
+		end_points = hdp_get_end_points(rec);
+		if (!end_points) {
+			error("Error getting end points");
+			continue;
+		}
+		aux = g_new0(struct health_instances_aux, 1);
+		aux->handler = rec->handle;
+		aux->data_spec = data_spec;
+		aux->end_points = end_points;
+		hdp_append_dict(dict, fill_up_instance, aux);
+		g_free(aux);
+	}
 }
 
 static void sink_health_instances(sdp_list_t *recs, int err, gpointer user_data)
@@ -129,11 +208,7 @@ static void sink_health_instances(sdp_list_t *recs, int err, gpointer user_data)
 	DBusMessage *msg = cb_data->msg;
 	struct hdp_device *device = cb_data->device;
 	DBusMessage *reply;
-	sdp_record_t *rec;
-	sdp_list_t *l;
-	guint8 data_spec;
-	GSList *end_points;
-	DBusMessageIter iter, dict;
+	DBusMessageIter iter;
 
 	g_free(cb_data);
 
@@ -151,34 +226,8 @@ static void sink_health_instances(sdp_list_t *recs, int err, gpointer user_data)
 
 	dbus_message_iter_init_append(reply, &iter);
 
-	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
-			DBUS_TYPE_ARRAY_AS_STRING
-			DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
-			DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
-			DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
-
-	for (l = recs; l; l = l->next) {
-		rec = l->data;
-		DBG("Record found 0x%x", rec->handle);
+	hdp_append_array_of_dicts(&iter, fill_up_health_instances, recs);
 
-		if (!hdp_get_data_exchange_spec(rec, &data_spec)) {
-			error("Error getting data exchange info");
-			continue;
-		}
-		end_points = hdp_get_end_points(rec);
-		if (!end_points) {
-			error("Error getting end points");
-			continue;
-		}
-		append_array_entry(&dict, &rec->handle, &data_spec,
-								end_points);
-	}
-
-	dbus_message_iter_close_container(&iter, &dict);
-/*
-	reply = g_dbus_create_error(msg, ERROR_INTERFACE ".HealthError",
-							"Not implemented yet");
-*/
 	g_dbus_send_message(device->conn, reply);
 }
 
diff --git a/health/hdp_util.c b/health/hdp_util.c
index 2f09417..921a1e1 100644
--- a/health/hdp_util.c
+++ b/health/hdp_util.c
@@ -328,9 +328,9 @@ static gboolean parse_role(DBusMessageIter *iter, GError **err, gpointer data)
 	}
 
 	dbus_message_iter_get_basic(string, &role);
-	if (g_strcmp0(role, "sink") == 0)
+	if (g_strcmp0(role, HDP_SINK_ROLE_AS_STRING) == 0)
 		fts->role = HDP_SINK;
-	else if (g_strcmp0(role, "source") == 0)
+	else if (g_strcmp0(role, HDP_SOURCE_ROLE_AS_STRING) == 0)
 		fts->role = HDP_SOURCE;
 	else {
 		g_set_error(err, HDP_ERROR, HDP_UNSPECIFIED_ERROR,
@@ -949,3 +949,55 @@ GSList *hdp_get_end_points(const sdp_record_t *rec)
 
 	return epl;
 }
+
+void hdp_append_array_of_dicts(DBusMessageIter *iter, hdp_dbus_fill_up fill_up,
+							gpointer user_data)
+{
+	DBusMessageIter dict;
+
+	dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
+			DBUS_TYPE_ARRAY_AS_STRING
+			DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+			DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
+			DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
+
+	fill_up(&dict, user_data);
+
+	dbus_message_iter_close_container(iter, &dict);
+}
+
+void hdp_append_dict(DBusMessageIter *iter, hdp_dbus_fill_up fill_up,
+							gpointer user_data)
+{
+	DBusMessageIter entry;
+
+	dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
+			DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+			DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
+			DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &entry);
+
+	fill_up(&entry, user_data);
+
+	dbus_message_iter_close_container(iter, &entry);
+}
+
+void hdp_append_variant_array_entry(DBusMessageIter *iter, char *key,
+				hdp_dbus_fill_up fill_up, gpointer user_data)
+{
+	DBusMessageIter entry, array;
+
+	dbus_message_iter_open_container(iter, DBUS_TYPE_DICT_ENTRY,
+								NULL, &entry);
+	dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
+	dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT,
+			DBUS_TYPE_ARRAY_AS_STRING
+			DBUS_TYPE_ARRAY_AS_STRING
+			DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+			DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
+			DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &array);
+
+	fill_up(&array, user_data);
+
+	dbus_message_iter_close_container(&entry, &array);
+	dbus_message_iter_close_container(iter, &entry);
+}
diff --git a/health/hdp_util.h b/health/hdp_util.h
index beafa00..08e6471 100644
--- a/health/hdp_util.h
+++ b/health/hdp_util.h
@@ -29,10 +29,22 @@
 #include <gdbus.h>
 #include "hdp_types.h"
 
+#define HDP_SINK_ROLE_AS_STRING	"sink"
+#define HDP_SOURCE_ROLE_AS_STRING	"source"
+
+typedef void (*hdp_dbus_fill_up)(DBusMessageIter *iter, gpointer data);
+
 struct hdp_config *hdp_get_config(DBusMessageIter *iter, GError **err);
 gboolean hdp_register_sdp_record(struct hdp_instance *hdps);
 gboolean hdp_get_data_exchange_spec(const sdp_record_t *rec, guint8 *val);
 GSList *hdp_get_end_points(const sdp_record_t *rec);
 void hdp_instance_free(struct hdp_instance *hdpi);
 
+void hdp_append_array_of_dicts(DBusMessageIter *iter, hdp_dbus_fill_up fill_up,
+							gpointer user_data);
+void hdp_append_dict(DBusMessageIter *iter, hdp_dbus_fill_up fil_up,
+							gpointer user_data);
+void hdp_append_variant_array_entry(DBusMessageIter *iter, char *key,
+				hdp_dbus_fill_up fill_up, gpointer user_data);
+
 #endif /* __HDP_UTIL_H__ */
-- 
1.6.3.3


^ permalink raw reply related

* [PATCH 11/32] Initial support for connecting instances
From: Jose Antonio Santos Cadenas @ 2010-06-04  8:30 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Jose Antonio Santos Cadenas
In-Reply-To: <1275640225-4186-11-git-send-email-santoscadenas@gmail.com>

---
 health/hdp.c |   62 ++++++++++++++++++++++++++++++++++++++++++++++-----------
 1 files changed, 50 insertions(+), 12 deletions(-)

diff --git a/health/hdp.c b/health/hdp.c
index 8690f0e..8bb6057 100644
--- a/health/hdp.c
+++ b/health/hdp.c
@@ -76,6 +76,16 @@ static struct hdp_device *find_device(GSList *devices, struct btd_device *dev)
 	return NULL;
 }
 
+static int hdp_instance_idcmp(gconstpointer instance, gconstpointer p)
+{
+	const struct hdp_instance *hdpi = instance;
+	const uint32_t *id = p;
+
+	if (hdpi->id == *id)
+		return 0;
+	return -1;
+}
+
 static void append_dict_features(DBusMessageIter *iter, GSList *end_points)
 {
 	DBusMessageIter entry, array;
@@ -225,9 +235,40 @@ static void dev_path_unregister(void *data)
 	health_device_free(device);
 }
 
+static DBusMessage *hdp_connect(DBusConnection *conn,
+					DBusMessage *msg, void *user_data)
+{
+	struct hdp_device *device = user_data;
+	struct hdp_instance *hdpi;
+	uint32_t lid, rid;
+	GSList *l;
+
+	if (!dbus_message_get_args(msg, NULL,
+					DBUS_TYPE_UINT32, &lid,
+					DBUS_TYPE_UINT32, &rid,
+					DBUS_TYPE_INVALID)) {
+		return g_dbus_create_error(msg,
+					ERROR_INTERFACE ".InvalidArguments",
+					"Invalid arguments in method call");
+	}
+
+	l = g_slist_find_custom(device->hdp_adapter->instances, &lid,
+							hdp_instance_idcmp);
+	if (!l)
+		return g_dbus_create_error(msg,
+					   ERROR_INTERFACE ".InvalidArguments",
+					   "Invalid local instance id");
+	hdpi = l->data;
+
+
+	return g_dbus_create_error(msg, ERROR_INTERFACE ".HdpError",
+					"Function is not yet implemented");
+}
+
 static GDBusMethodTable device_methods[] = {
 	{ "GetHealthInstances", "", "aa{sv}", get_health_instances,
 						G_DBUS_METHOD_FLAG_ASYNC },
+	{ "Connect", "uu", "o", hdp_connect, G_DBUS_METHOD_FLAG_ASYNC },
 	{ NULL }
 };
 
@@ -235,33 +276,30 @@ static struct hdp_device *create_health_device(DBusConnection *conn,
 						struct btd_device *device)
 {
 	const gchar *path = device_get_path(device);
+	struct btd_adapter *adapter = device_get_adapter(device);
 	struct hdp_device *dev;
 
 	dev = g_new0(struct hdp_device, 1);
 	dev->conn = dbus_connection_ref(conn);
 	dev->dev = btd_device_ref(device);
+	dev->hdp_adapter = find_adapter(adapters, adapter);
+
+	if (!dev->hdp_adapter)
+		goto fail;
 
 	if (!g_dbus_register_interface(conn, path,
 					HEALTH_DEVICE,
 					device_methods, NULL, NULL,
 					dev, dev_path_unregister)) {
 		error("D-Bus failed to register %s interface", HEALTH_DEVICE);
-		health_device_free(dev);
-		return NULL;
+		goto fail;
 	}
 
 	DBG("Registered interface %s on path %s", HEALTH_DEVICE, path);
 	return dev;
-}
-
-static int hdp_instance_idcmp(gconstpointer instance, gconstpointer p)
-{
-	const struct hdp_instance *hdpi = instance;
-	const uint32_t *id = p;
-
-	if (hdpi->id == *id)
-		return 0;
-	return -1;
+fail:
+	health_device_free(dev);
+	return NULL;
 }
 
 static void hdp_set_instance_id(struct hdp_instance *hdpi)
-- 
1.6.3.3


^ permalink raw reply related


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