Diff between 6e3b013a66901957d76f25116e28927c6de4efc0 and 76041ebc6b7b6a9cb95040ec6a824c2fea75b2f1

Changed Files

File Additions Deletions Status
src/manager.c +9 -0 modified
src/profile.c +125 -0 modified
src/profile.h +5 -0 modified

Full Patch

diff --git a/src/manager.c b/src/manager.c
index 15a2571..90e6e6b 100644
--- a/src/manager.c
+++ b/src/manager.c
@@ -28,6 +28,7 @@
 
 #include <stdlib.h>
 #include <stdio.h>
+#include <stdbool.h>
 #include <errno.h>
 #include <unistd.h>
 #include <sys/ioctl.h>
@@ -48,6 +49,8 @@
 #include "dbus-common.h"
 #include "log.h"
 #include "adapter.h"
+#include "device.h"
+#include "profile.h"
 #include "error.h"
 #include "manager.h"
 
@@ -176,6 +179,12 @@ static const GDBusMethodTable manager_methods[] = {
 			GDBUS_ARGS({ "pattern", "s" }),
 			GDBUS_ARGS({ "adapter", "o" }),
 			find_adapter) },
+	{ GDBUS_METHOD("RegisterProfile",
+			GDBUS_ARGS({ "profile", "o"}, { "UUID", "s" },
+						{ "options", "a{sv}" }),
+			NULL, btd_profile_reg_ext) },
+	{ GDBUS_METHOD("UnregisterProfile", GDBUS_ARGS({ "profile", "o" }),
+			NULL, btd_profile_unreg_ext) },
 	{ }
 };
 
diff --git a/src/profile.c b/src/profile.c
index 5b40b16..aa76a91 100644
--- a/src/profile.c
+++ b/src/profile.c
@@ -31,11 +31,22 @@
 #include <glib.h>
 #include <dbus/dbus.h>
 
+#include "uuid.h"
+#include "error.h"
 #include "adapter.h"
 #include "device.h"
 #include "profile.h"
 
+struct ext_profile {
+	struct btd_profile p;
+	char *name;
+	char *owner;
+	char *uuid;
+	char *path;
+};
+
 static GSList *profiles = NULL;
+static GSList *ext_profiles = NULL;
 
 void btd_profile_foreach(void (*func)(struct btd_profile *p, void *data),
 								void *data)
@@ -49,6 +60,14 @@ void btd_profile_foreach(void (*func)(struct btd_profile *p, void *data),
 
 		func(profile, data);
 	}
+
+	for (l = ext_profiles; l != NULL; l = next) {
+		struct ext_profile *profile = l->data;
+
+		next = g_slist_next(l);
+
+		func(&profile->p, data);
+	}
 }
 
 int btd_profile_register(struct btd_profile *profile)
@@ -61,3 +80,109 @@ void btd_profile_unregister(struct btd_profile *profile)
 {
 	profiles = g_slist_remove(profiles, profile);
 }
+
+static struct ext_profile *find_ext_profile(const char *owner,
+						const char *path)
+{
+	GSList *l;
+
+	for (l = ext_profiles; l != NULL; l = g_slist_next(l)) {
+		struct ext_profile *ext = l->data;
+
+		if (!g_str_equal(ext->owner, owner))
+			continue;
+
+		if (g_str_equal(ext->path, path))
+			return ext;
+	}
+
+	return NULL;
+}
+
+static struct ext_profile *create_ext(const char *owner, const char *path,
+					const char *uuid,
+					DBusMessageIter *opts)
+{
+	struct btd_profile *p;
+	struct ext_profile *ext;
+
+	ext = g_new0(struct ext_profile, 1);
+
+	ext->name = g_strdup_printf("%s-%s/%s", owner, path, uuid);
+	ext->owner = g_strdup(owner);
+	ext->path = g_strdup(path);
+	ext->uuid = g_strdup(uuid);
+
+	p = &ext->p;
+
+	p->name = ext->name;
+
+	ext_profiles = g_slist_append(ext_profiles, ext);
+
+	return ext;
+}
+
+static void remove_ext(struct ext_profile *ext)
+{
+	ext_profiles = g_slist_remove(ext_profiles, ext);
+
+	g_free(ext->name);
+	g_free(ext->owner);
+	g_free(ext->uuid);
+	g_free(ext->path);
+
+	g_free(ext);
+}
+
+DBusMessage *btd_profile_reg_ext(DBusConnection *conn, DBusMessage *msg,
+							void *user_data)
+{
+	const char *path, *sender, *uuid;
+	DBusMessageIter args, opts;
+	struct ext_profile *ext;
+
+	sender = dbus_message_get_sender(msg);
+
+	dbus_message_iter_init(msg, &args);
+
+	dbus_message_iter_get_basic(&args, &path);
+	dbus_message_iter_next(&args);
+
+	ext = find_ext_profile(sender, path);
+	if (ext)
+		return btd_error_already_exists(msg);
+
+	dbus_message_iter_get_basic(&args, &uuid);
+	dbus_message_iter_next(&args);
+
+	dbus_message_iter_recurse(&args, &opts);
+	if (dbus_message_iter_get_arg_type(&opts) != DBUS_TYPE_DICT_ENTRY)
+		return btd_error_invalid_args(msg);
+
+	ext = create_ext(sender, path, uuid, &opts);
+	if (!ext)
+		return btd_error_invalid_args(msg);
+
+	return dbus_message_new_method_return(msg);
+}
+
+DBusMessage *btd_profile_unreg_ext(DBusConnection *conn, DBusMessage *msg,
+							void *user_data)
+{
+	const char *path, *sender;
+	struct ext_profile *ext;
+
+	sender = dbus_message_get_sender(msg);
+
+	if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
+							DBUS_TYPE_INVALID))
+		return btd_error_invalid_args(msg);
+
+	ext = find_ext_profile(sender, path);
+	if (!ext)
+		return btd_error_does_not_exist(msg);
+
+	remove_ext(ext);
+
+	return dbus_message_new_method_return(msg);
+}
diff --git a/src/profile.h b/src/profile.h
index 0e73ef4..178e7bf 100644
--- a/src/profile.h
+++ b/src/profile.h
@@ -52,3 +52,8 @@ void btd_profile_foreach(void (*func)(struct btd_profile *p, void *data),
 
 int btd_profile_register(struct btd_profile *profile);
 void btd_profile_unregister(struct btd_profile *profile);
+
+DBusMessage *btd_profile_reg_ext(DBusConnection *conn, DBusMessage *msg,
+							void *user_data);
+DBusMessage *btd_profile_unreg_ext(DBusConnection *conn, DBusMessage *msg,
+							void *user_data);