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

_______________________________________________
ofono mailing list
[email protected]
http://lists.ofono.org/listinfo/ofono

Reply via email to