From: Vinicius Costa Gomes <[email protected]>

This patch adds NewConnection message arguments parsing: features,
version and Media Endpoints included in the fd_properties dictionary.
---
 plugins/bluez5.c        |  35 ++++++++++++
 plugins/bluez5.h        |   8 +++
 plugins/hfp_hf_bluez5.c | 149 +++++++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 189 insertions(+), 3 deletions(-)

diff --git a/plugins/bluez5.c b/plugins/bluez5.c
index 589658a..d753ac9 100644
--- a/plugins/bluez5.c
+++ b/plugins/bluez5.c
@@ -36,6 +36,41 @@
 
 #define BLUEZ_PROFILE_MGMT_INTERFACE   BLUEZ_SERVICE ".ProfileManager1"
 
+struct bt_endpoint {
+       char *owner;
+       char *path;
+       guint8 codec;
+       unsigned char *capa;    /* Capabilities */
+       int capa_size;          /* Capabilities size */
+};
+
+struct bt_endpoint *bt_endpoint_new(const char *owner,
+                                       const char *path, guint8 codec,
+                                       unsigned char *capa, int capa_size)
+{
+       struct bt_endpoint *endpoint;
+
+       endpoint = g_new0(struct bt_endpoint, 1);
+       endpoint->owner = g_strdup(owner);
+       endpoint->path = g_strdup(path);
+       endpoint->codec = codec;
+       if (capa && capa_size)
+               endpoint->capa = g_memdup(capa, capa_size);
+
+       return endpoint;
+}
+
+void bt_endpoint_free(gpointer data)
+{
+       struct bt_endpoint *endpoint = data;
+
+       g_free(endpoint->owner);
+       g_free(endpoint->path);
+       if (endpoint->capa)
+               g_free(endpoint->capa);
+       g_free(endpoint);
+}
+
 static void profile_register_cb(DBusPendingCall *call, gpointer user_data)
 {
        DBusMessage *reply;
diff --git a/plugins/bluez5.h b/plugins/bluez5.h
index 3088c7d..1ab350e 100644
--- a/plugins/bluez5.h
+++ b/plugins/bluez5.h
@@ -25,6 +25,14 @@
 
 #define HFP_HS_UUID    "0000111e-0000-1000-8000-00805f9b34fb"
 
+struct bt_endpoint;
+
+struct bt_endpoint *bt_endpoint_new(const char *owner,
+                                       const char *path, guint8 codec,
+                                       unsigned char *capa, int capa_size);
+
+void bt_endpoint_free(gpointer data);
+
 int bt_register_profile(DBusConnection *conn, const char *uuid,
                                        const char *name, const char *object);
 
diff --git a/plugins/hfp_hf_bluez5.c b/plugins/hfp_hf_bluez5.c
index f1f8891..ef9af62 100644
--- a/plugins/hfp_hf_bluez5.c
+++ b/plugins/hfp_hf_bluez5.c
@@ -25,6 +25,7 @@
 
 #include <errno.h>
 #include <glib.h>
+#include <string.h>
 
 #include <gdbus.h>
 
@@ -42,6 +43,111 @@
 
 #define HFP_EXT_PROFILE_PATH   "/bluetooth/profile/hfp_hf"
 
+struct capabilities {
+       unsigned char *value;
+       int size;
+};
+
+static void parse_guint16(DBusMessageIter *iter, gpointer user_data)
+{
+       guint16 *value = user_data;
+
+       if (dbus_message_iter_get_arg_type(iter) !=  DBUS_TYPE_UINT16)
+               return;
+
+       dbus_message_iter_get_basic(iter, value);
+}
+
+static void parse_string(DBusMessageIter *iter, gpointer user_data)
+{
+       char **str = user_data;
+       int arg_type = dbus_message_iter_get_arg_type(iter);
+
+       if (arg_type != DBUS_TYPE_OBJECT_PATH && arg_type != DBUS_TYPE_STRING)
+               return;
+
+       dbus_message_iter_get_basic(iter, str);
+}
+
+static void parse_byte(DBusMessageIter *iter, gpointer user_data)
+{
+       guint8 *value = user_data;
+
+       if (dbus_message_iter_get_arg_type(iter) !=  DBUS_TYPE_BYTE)
+               return;
+
+       dbus_message_iter_get_basic(iter, value);
+}
+
+static void parse_capabilities(DBusMessageIter *iter, gpointer user_data)
+{
+       DBusMessageIter array;
+       struct capabilities *capa = user_data;
+       guint8 *data = NULL;
+       int n = 0;
+
+       if (dbus_message_iter_get_arg_type(iter) !=  DBUS_TYPE_ARRAY)
+               return;
+
+       dbus_message_iter_recurse(iter, &array);
+       dbus_message_iter_get_fixed_array(&array, &data, &n);
+       if (n == 0)
+               return;
+
+       capa->value = g_memdup(data, n);
+       capa->size = n;
+}
+
+static void parse_media_endpoints(DBusMessageIter *array, gpointer user_data)
+{
+       const char *path, *owner;
+       GSList **endpoints = user_data;
+       struct capabilities capa;
+       struct bt_endpoint *endpoint;
+       guint8 codec;
+       DBusMessageIter dict, variant, entry;
+
+       if (dbus_message_iter_get_arg_type(array) != DBUS_TYPE_ARRAY)
+               return;
+
+       dbus_message_iter_recurse(array, &dict);
+
+       while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
+               path = NULL;
+               codec = 0x00;
+
+               dbus_message_iter_recurse(&dict, &entry);
+               if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_STRING)
+                       return;
+
+               dbus_message_iter_get_basic(&entry, &owner);
+
+               dbus_message_iter_next(&entry);
+
+               if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_VARIANT)
+                       return;
+
+               dbus_message_iter_recurse(&entry, &variant);
+
+               memset(&capa, 0, sizeof(capa));
+               ofono_dbus_iter_parse_properties(&variant,
+                               "Path", parse_string, &path,
+                               "Codec", parse_byte, &codec,
+                               "Capabilities", parse_capabilities, &capa,
+                               NULL);
+
+               dbus_message_iter_next(&dict);
+
+               endpoint = bt_endpoint_new(owner, path, codec,
+                                               capa.value, capa.size);
+
+               g_free(capa.value);
+               *endpoints = g_slist_append(*endpoints, endpoint);
+
+               DBG("Media Endpoint %s %s codec: 0x%02X", owner, path, codec);
+       }
+}
+
 static int hfp_probe(struct ofono_modem *modem)
 {
        DBG("modem: %p", modem);
@@ -93,11 +199,48 @@ static struct ofono_modem_driver hfp_driver = {
 static DBusMessage *profile_new_connection(DBusConnection *conn,
                                        DBusMessage *msg, void *user_data)
 {
+       DBusMessageIter entry;
+       const char *device;
+       GSList *endpoints = NULL;
+       guint16 version, features;
+       int fd;
+
        DBG("Profile handler NewConnection");
 
-       return g_dbus_create_error(msg, BLUEZ_ERROR_INTERFACE
-                                       ".NotImplemented",
-                                       "Implementation not provided");
+       if (dbus_message_iter_init(msg, &entry) == FALSE)
+               goto error;
+
+       if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_OBJECT_PATH)
+               goto error;
+
+       dbus_message_iter_get_basic(&entry, &device);
+       dbus_message_iter_next(&entry);
+       if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_UNIX_FD)
+               goto error;
+
+       dbus_message_iter_get_basic(&entry, &fd);
+       if (fd < 0)
+               goto error;
+
+       dbus_message_iter_next(&entry);
+
+       ofono_dbus_iter_parse_properties(&entry,
+                       "Version", parse_guint16, &version,
+                       "Features", parse_guint16, &features,
+                       "MediaEndpoints", parse_media_endpoints, &endpoints,
+                       NULL);
+
+       DBG("%s version: 0x%04x features: 0x%04x", device, version, features);
+
+       if (endpoints == NULL) {
+               ofono_error("Media Endpoint missing");
+               goto error;
+       }
+       return NULL;
+
+error:
+       return g_dbus_create_error(msg, BLUEZ_ERROR_INTERFACE ".Rejected",
+                                       "Invalid arguments in method call");
 }
 
 static DBusMessage *profile_release(DBusConnection *conn,
-- 
1.7.11.7

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

Reply via email to