From b61dbfeba412dec291953724a92c6306f197643e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 31 Mar 2009 19:30:28 -0700 Subject: [PATCH] Add basic automatic clustering support for networks --- src/connman.h | 2 + src/network.c | 5 +++ src/profile.c | 127 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 131 insertions(+), 3 deletions(-) diff --git a/src/connman.h b/src/connman.h index 128c084..add13ae 100644 --- a/src/connman.h +++ b/src/connman.h @@ -196,6 +196,8 @@ int __connman_network_disconnect(struct connman_network *network); connman_bool_t __connman_network_has_driver(struct connman_network *network); +const char *__connman_network_get_group(struct connman_network *network); + int __connman_profile_add_network(struct connman_network *network); int __connman_profile_remove_network(struct connman_network *network); diff --git a/src/network.c b/src/network.c index 754380d..94e90ee 100644 --- a/src/network.c +++ b/src/network.c @@ -588,6 +588,11 @@ void connman_network_set_group(struct connman_network *network, network->group = g_strdup(group); } +const char *__connman_network_get_group(struct connman_network *network) +{ + return network->group; +} + /** * connman_network_set_available: * @network: network structure diff --git a/src/profile.c b/src/profile.c index d1aea70..4300520 100644 --- a/src/profile.c +++ b/src/profile.c @@ -28,31 +28,109 @@ #include "connman.h" +#define PROFILE_DEFAULT "/profile/default" + +struct connman_group { + char *path; + GSList *networks; +}; + +static GHashTable *groups = NULL; + +static void free_group(gpointer data) +{ + struct connman_group *group = data; + + DBG("group %p", group); + + g_free(group->path); + g_free(group); +} + +static struct connman_group *lookup_group(const char *name) +{ + struct connman_group *group; + + DBG("name %s", name); + + if (name == NULL) + return NULL; + + group = g_hash_table_lookup(groups, name); + if (group != NULL) + goto done; + + group = g_try_new0(struct connman_group, 1); + if (group == NULL) + return NULL; + + group->path = g_strdup_printf("%s/%s", PROFILE_DEFAULT, name); + + g_hash_table_insert(groups, g_strdup(name), group); + +done: + DBG("group %p", group); + + return group; +} + int __connman_profile_add_device(struct connman_device *device) { + struct connman_group *group; + char *name; + DBG("device %p", device); + name = g_strdup_printf("device%d", connman_device_get_index(device)); + group = lookup_group(name); + g_free(name); + + if (group == NULL) + return -EINVAL; + return 0; } int __connman_profile_remove_device(struct connman_device *device) { + struct connman_group *group; + char *name; + DBG("device %p", device); + name = g_strdup_printf("device%d", connman_device_get_index(device)); + group = lookup_group(name); + g_free(name); + + if (group == NULL) + return -EINVAL; + return 0; } int __connman_profile_add_network(struct connman_network *network) { + struct connman_group *group; + DBG("network %p", network); + group = lookup_group(__connman_network_get_group(network)); + if (group == NULL) + return -EINVAL; + return 0; } int __connman_profile_remove_network(struct connman_network *network) { + struct connman_group *group; + DBG("network %p", network); + group = lookup_group(__connman_network_get_group(network)); + if (group == NULL) + return -EINVAL; + return 0; } @@ -60,7 +138,7 @@ const char *__connman_profile_active(void) { DBG(""); - return "/profile/default"; + return PROFILE_DEFAULT; } void __connman_profile_list(DBusMessageIter *iter) @@ -72,9 +150,44 @@ void __connman_profile_list(DBusMessageIter *iter) dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH, &path); } +static void append_path(gpointer key, gpointer value, gpointer user_data) +{ + struct connman_group *group = value; + DBusMessageIter *iter = user_data; + + dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH, + &group->path); +} + void __connman_profile_list_services(DBusMessageIter *iter) { DBG(""); + + g_hash_table_foreach(groups, append_path, iter); +} + +static void append_services(DBusMessageIter *dict) +{ + DBusMessageIter entry, value, iter; + const char *key = "Services"; + + dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY, + NULL, &entry); + + dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key); + + dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT, + DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_OBJECT_PATH_AS_STRING, + &value); + + dbus_message_iter_open_container(&value, DBUS_TYPE_ARRAY, + DBUS_TYPE_OBJECT_PATH_AS_STRING, &iter); + __connman_profile_list_services(&iter); + dbus_message_iter_close_container(&value, &iter); + + dbus_message_iter_close_container(&entry, &value); + + dbus_message_iter_close_container(dict, &entry); } static DBusMessage *get_properties(DBusConnection *conn, @@ -100,6 +213,8 @@ static DBusMessage *get_properties(DBusConnection *conn, connman_dbus_dict_append_variant(&dict, "Name", DBUS_TYPE_STRING, &name); + append_services(&dict); + dbus_message_iter_close_container(&array, &dict); return reply; @@ -120,7 +235,10 @@ int __connman_profile_init(DBusConnection *conn) if (connection == NULL) return -1; - g_dbus_register_interface(connection, "/profile/default", + groups = g_hash_table_new_full(g_str_hash, g_str_equal, + g_free, free_group); + + g_dbus_register_interface(connection, PROFILE_DEFAULT, CONNMAN_PROFILE_INTERFACE, profile_methods, NULL, NULL, NULL, NULL); @@ -132,9 +250,12 @@ void __connman_profile_cleanup(void) { DBG("conn %p", connection); - g_dbus_unregister_interface(connection, "/profile/default", + g_dbus_unregister_interface(connection, PROFILE_DEFAULT, CONNMAN_PROFILE_INTERFACE); + g_hash_table_destroy(groups); + groups = NULL; + if (connection == NULL) return; -- 2.7.4