All of lore.kernel.org
 help / color / mirror / Atom feed
From: =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis <frederic.danis@linux.intel.com>
To: ofono@ofono.org
Subject: [RFC v4 01/10] bluetooth: Add org.bluez.Telephony helpers
Date: Fri, 06 Apr 2012 15:17:03 +0200	[thread overview]
Message-ID: <1333718232-8447-2-git-send-email-frederic.danis@linux.intel.com> (raw)
In-Reply-To: <1333718232-8447-1-git-send-email-frederic.danis@linux.intel.com>

[-- Attachment #1: Type: text/plain, Size: 8320 bytes --]

Add function to register/unregister Telephony agent to BlueZ
---
 plugins/bluetooth.c |  198 +++++++++++++++++++++++++++++++++++++++++++++++++++
 plugins/bluetooth.h |   14 ++++
 2 files changed, 212 insertions(+), 0 deletions(-)

diff --git a/plugins/bluetooth.c b/plugins/bluetooth.c
index dbf79eb..971e2c6 100644
--- a/plugins/bluetooth.c
+++ b/plugins/bluetooth.c
@@ -44,6 +44,7 @@ static GHashTable *uuid_hash = NULL;
 static GHashTable *adapter_address_hash = NULL;
 static gint bluetooth_refcount;
 static GSList *server_list = NULL;
+static GSList *telephony_list = NULL;
 static const char *adapter_any_name = "any";
 static char *adapter_any_path;
 
@@ -65,6 +66,13 @@ struct cb_data {
 	GIOChannel *io;
 };
 
+struct agent {
+	char *path;
+	char *uuid;
+	guint16 version;
+	guint16 features;
+};
+
 void bluetooth_create_path(const char *dev_addr, const char *adapter_addr,
 				char *buf, int size)
 {
@@ -146,6 +154,60 @@ fail:
 	return err;
 }
 
+static void register_telephony_agent(const char *path, const char *handle,
+						struct agent *agent)
+{
+	DBusMessage *msg;
+	DBusMessageIter iter, dict;
+
+	DBG("Registering oFono Agent for %s to %s", agent->uuid, path);
+
+	msg = dbus_message_new_method_call(BLUEZ_SERVICE, path,
+				BLUEZ_TELEPHONY_INTERFACE, "RegisterAgent");
+	if (msg == NULL)
+		return;
+
+	dbus_message_iter_init_append(msg, &iter);
+
+	dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
+							&agent->path);
+
+	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);
+
+	ofono_dbus_dict_append(&dict, "UUID", DBUS_TYPE_STRING, &agent->uuid);
+
+	ofono_dbus_dict_append(&dict, "Version", DBUS_TYPE_UINT16,
+							&agent->version);
+	ofono_dbus_dict_append(&dict, "Features", DBUS_TYPE_UINT16,
+							&agent->features);
+
+	dbus_message_iter_close_container(&iter, &dict);
+
+	g_dbus_send_message(connection, msg);
+}
+
+static void unregister_telephony_agent(const char *path, const char *handle,
+						struct agent *agent)
+{
+	DBusMessage *msg;
+
+	DBG("Unregistering oFono Agent for %s from %s", agent->uuid, path);
+
+	msg = dbus_message_new_method_call(BLUEZ_SERVICE, path,
+					BLUEZ_TELEPHONY_INTERFACE,
+					"UnregisterAgent");
+	if (msg == NULL)
+		return;
+
+	dbus_message_append_args(msg, DBUS_TYPE_OBJECT_PATH, &agent->path,
+					DBUS_TYPE_INVALID);
+
+	g_dbus_send_message(connection, msg);
+}
+
 typedef void (*PropertyHandler)(DBusMessageIter *iter, gpointer user_data);
 
 struct property_handler {
@@ -455,6 +517,9 @@ static void adapter_properties_cb(DBusPendingCall *call, gpointer user_data)
 					g_free, -1, DBUS_TYPE_INVALID);
 	}
 
+	for (l = telephony_list; l; l = l->next)
+		register_telephony_agent(path, NULL, l->data);
+
 done:
 	g_slist_free(device_list);
 	dbus_message_unref(reply);
@@ -982,5 +1047,138 @@ void bluetooth_unregister_server(struct server *server)
 	bluetooth_unref();
 }
 
+int bluetooth_parse_newconnection_message(DBusMessage *msg, const char **device,
+					const char **uuid, guint16 *version,
+					guint16 *features,
+					const char **transport_path)
+{
+	DBusMessageIter args, props;
+	int fd;
+	gboolean has_device = FALSE;
+	gboolean has_uuid = FALSE;
+
+	dbus_message_iter_init(msg, &args);
+
+	if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_UNIX_FD)
+		return -EINVAL;
+
+	dbus_message_iter_get_basic(&args, &fd);
+	dbus_message_iter_next(&args);
+
+	dbus_message_iter_recurse(&args, &props);
+	if (dbus_message_iter_get_arg_type(&props) != DBUS_TYPE_DICT_ENTRY)
+		return -EINVAL;
+
+	while (dbus_message_iter_get_arg_type(&props) == DBUS_TYPE_DICT_ENTRY) {
+		const char *key;
+		DBusMessageIter value, entry;
+		int var;
+
+		dbus_message_iter_recurse(&props, &entry);
+		dbus_message_iter_get_basic(&entry, &key);
+
+		dbus_message_iter_next(&entry);
+		dbus_message_iter_recurse(&entry, &value);
+
+		var = dbus_message_iter_get_arg_type(&value);
+		if (strcasecmp(key, "Device") == 0) {
+			if (var != DBUS_TYPE_OBJECT_PATH)
+				return -EINVAL;
+			dbus_message_iter_get_basic(&value, device);
+			has_device = TRUE;
+		} else if (strcasecmp(key, "UUID") == 0) {
+			if (var != DBUS_TYPE_STRING)
+				return -EINVAL;
+			dbus_message_iter_get_basic(&value, uuid);
+			has_uuid = TRUE;
+		} else if (strcasecmp(key, "Version") == 0) {
+			if (var != DBUS_TYPE_UINT16)
+				return -EINVAL;
+			dbus_message_iter_get_basic(&value, version);
+		} else if (strcasecmp(key, "Features") == 0) {
+			if (var != DBUS_TYPE_UINT16)
+				return -EINVAL;
+			dbus_message_iter_get_basic(&value, features);
+		} else if (strcasecmp(key, "Transport") == 0) {
+			if (var != DBUS_TYPE_OBJECT_PATH)
+				return -EINVAL;
+			dbus_message_iter_get_basic(&value, transport_path);
+		}
+
+		dbus_message_iter_next(&props);
+	}
+
+	return (has_device && has_uuid) ? fd : -EINVAL;
+}
+
+void bluetooth_register_telephony_agent(const char *path, const char *uuid,
+					guint16 version, guint16 features,
+					const GDBusMethodTable *methods,
+					void *user_data,
+					GDBusDestroyFunction destroy)
+{
+	GSList *l;
+	struct agent *agent;
+
+	for (l = telephony_list; l; l = l->next) {
+		agent = l->data;
+
+		if (g_strcmp0(path, agent->path) == 0) {
+			ofono_error("Telephony agent path \"%s\" already " \
+					"registered", path);
+			return;
+		}
+	}
+
+	agent = g_try_new0(struct agent, 1);
+	if (!agent)
+		return;
+
+	agent->path = g_strdup(path);
+	agent->uuid = g_strdup(uuid);
+	agent->version = version;
+	agent->features = features;
+
+	bluetooth_ref();
+
+	g_dbus_register_interface(connection, path,
+				BLUEZ_TELEPHONY_AGENT_INTERFACE, methods, NULL,
+				NULL, user_data, destroy);
+
+	telephony_list = g_slist_prepend(telephony_list, agent);
+
+	g_hash_table_foreach(adapter_address_hash,
+			(GHFunc) register_telephony_agent, agent);
+}
+
+void bluetooth_unregister_telephony_agent(const char *path)
+{
+	GSList *l;
+	struct agent *agent;
+
+	for (l = telephony_list; l; l = l->next) {
+		agent = l->data;
+
+		if (g_strcmp0(path, agent->path) == 0)
+			break;
+	}
+
+	if (l == NULL)
+		return;
+
+	g_hash_table_foreach(adapter_address_hash,
+			(GHFunc) unregister_telephony_agent, agent);
+
+	telephony_list = g_slist_remove(telephony_list, agent);
+	g_free(agent->path);
+	g_free(agent->uuid);
+	g_free(agent);
+
+	g_dbus_unregister_interface(connection, path,
+				BLUEZ_TELEPHONY_AGENT_INTERFACE);
+
+	bluetooth_unref();
+}
+
 OFONO_PLUGIN_DEFINE(bluetooth, "Bluetooth Utils Plugins", VERSION,
 			OFONO_PLUGIN_PRIORITY_DEFAULT, NULL, NULL)
diff --git a/plugins/bluetooth.h b/plugins/bluetooth.h
index daa1873..f81fc99 100644
--- a/plugins/bluetooth.h
+++ b/plugins/bluetooth.h
@@ -21,12 +21,15 @@
 
 #include <ofono/modem.h>
 #include <ofono/dbus.h>
+#include <gdbus.h>
 
 #define	BLUEZ_SERVICE "org.bluez"
 #define	BLUEZ_MANAGER_INTERFACE		BLUEZ_SERVICE ".Manager"
 #define	BLUEZ_ADAPTER_INTERFACE		BLUEZ_SERVICE ".Adapter"
 #define	BLUEZ_DEVICE_INTERFACE		BLUEZ_SERVICE ".Device"
 #define	BLUEZ_SERVICE_INTERFACE		BLUEZ_SERVICE ".Service"
+#define	BLUEZ_TELEPHONY_INTERFACE	BLUEZ_SERVICE ".Telephony"
+#define	BLUEZ_TELEPHONY_AGENT_INTERFACE	BLUEZ_SERVICE ".TelephonyAgent"
 
 #define DBUS_TIMEOUT 15
 
@@ -81,3 +84,14 @@ void bluetooth_parse_properties(DBusMessage *reply, const char *property, ...);
 int bluetooth_sap_client_register(struct bluetooth_sap_driver *sap,
 					struct ofono_modem *modem);
 void bluetooth_sap_client_unregister(struct ofono_modem *modem);
+
+int bluetooth_parse_newconnection_message(DBusMessage *msg, const char **device,
+					const char **uuid, guint16 *version,
+					guint16 *features,
+					const char **transport_path);
+void bluetooth_register_telephony_agent(const char *path, const char *uuid,
+					guint16 version, guint16 features,
+					const GDBusMethodTable *methods,
+					void *user_data,
+					GDBusDestroyFunction destroy);
+void bluetooth_unregister_telephony_agent(const char *path);
-- 
1.7.1


  reply	other threads:[~2012-04-06 13:17 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-04-06 13:17 [RFC v4 00/10] org.bluez.Telephony interface integration =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
2012-04-06 13:17 ` =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis [this message]
2012-04-06 13:17 ` [RFC v4 02/10] hfp_hf: Update to org.bluez.Telephony interface =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
2012-04-06 13:17 ` [RFC v4 03/10] hfp_ag: " =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
2012-04-06 13:17 ` [RFC v4 04/10] bluetooth: Add audio APIs for HFP AG =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
2012-04-06 17:27   ` Denis Kenzior
2012-04-06 13:17 ` [RFC v4 05/10] bluetooth: Add AT+NREC support =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
2012-04-06 17:32   ` Denis Kenzior
2012-04-06 13:17 ` [RFC v4 06/10] bluetooth: Add +BSIR support =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
2012-04-06 13:17 ` [RFC v4 07/10] bluetooth: Add AT+VGM support =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
2012-04-06 13:17 ` [RFC v4 08/10] bluetooth: Add AT+VGS support =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
2012-04-06 13:17 ` [RFC v4 09/10] hfp_ag: Add media transport support =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
2012-04-06 17:38   ` Denis Kenzior
2012-04-24 16:19     ` Frederic Danis
2012-04-23 19:24       ` Denis Kenzior
2012-04-06 13:17 ` [RFC v4 10/10] emulator: Update supported features =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
2012-04-06 17:38   ` Denis Kenzior
2012-04-23 14:01     ` Frederic Danis
2012-04-23  0:03       ` Denis Kenzior

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1333718232-8447-2-git-send-email-frederic.danis@linux.intel.com \
    --to=frederic.danis@linux.intel.com \
    --cc=ofono@ofono.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.