diff --git a/src/manager.c b/src/manager.c
index 15a2571..90e6e6b 100644
--- a/src/manager.c
+++ b/src/manager.c
#include <stdlib.h>
#include <stdio.h>
+#include <stdbool.h>
#include <errno.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include "dbus-common.h"
#include "log.h"
#include "adapter.h"
+#include "device.h"
+#include "profile.h"
#include "error.h"
#include "manager.h"
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
#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)
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)
{
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
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);