From: =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis <frederic.danis@linux.intel.com>
To: ofono@ofono.org
Subject: [RFC 1/3] bluetooth: add org.bluez.Telephony helpers
Date: Tue, 31 Jan 2012 16:50:03 +0100 [thread overview]
Message-ID: <1328025005-12012-2-git-send-email-frederic.danis@linux.intel.com> (raw)
In-Reply-To: <1328025005-12012-1-git-send-email-frederic.danis@linux.intel.com>
[-- Attachment #1: Type: text/plain, Size: 8576 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..de2eb2c 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 {
@@ -702,6 +764,7 @@ static gboolean adapter_added(DBusConnection *connection, DBusMessage *message,
void *user_data)
{
const char *path;
+ GSList *l;
dbus_message_get_args(message, NULL, DBUS_TYPE_OBJECT_PATH, &path,
DBUS_TYPE_INVALID);
@@ -710,6 +773,9 @@ static gboolean adapter_added(DBusConnection *connection, DBusMessage *message,
"GetProperties", NULL, adapter_properties_cb,
g_strdup(path), g_free, -1, DBUS_TYPE_INVALID);
+ for (l = telephony_list; l; l = l->next)
+ register_telephony_agent(path, NULL, l->data);
+
return TRUE;
}
@@ -982,5 +1048,137 @@ 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);
+ } 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
next prev parent reply other threads:[~2012-01-31 15:50 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-01-31 15:50 [RFC 0/3] org.bluez.Telephony interface integration =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
2012-01-31 15:50 ` =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis [this message]
2012-01-31 15:50 ` [RFC 2/3] hfp_hf: update to org.bluez.Telephony interface =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
2012-01-31 15:50 ` [RFC 3/3] hfp_ag: " =?unknown-8bit?q?Fr=C3=A9d=C3=A9ric?= Danis
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=1328025005-12012-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.