Add support for creating and removing networks
authorMarcel Holtmann <marcel@holtmann.org>
Tue, 8 Apr 2008 05:38:33 +0000 (07:38 +0200)
committerMarcel Holtmann <marcel@holtmann.org>
Tue, 8 Apr 2008 05:38:33 +0000 (07:38 +0200)
include/iface.h
src/connman.h
src/iface-storage.c
src/iface.c
src/main.c
src/network.c

index 8b0e6c8..2123fea 100644 (file)
@@ -88,6 +88,8 @@ struct connman_ipv4 {
 };
 
 struct connman_network {
+       struct connman_iface *iface;
+       char *path;
        char *identifier;
        char *passphrase;
 };
index 90a70d9..9f9862a 100644 (file)
@@ -37,6 +37,8 @@
 #define CONNMAN_IFACE_BASEPATH  "/interface"
 #define CONNMAN_IFACE_INTERFACE  CONNMAN_SERVICE ".Interface"
 
+#define CONNMAN_NETWORK_INTERFACE  CONNMAN_SERVICE ".Network"
+
 #define NM_SERVICE    "org.freedesktop.NetworkManager"
 #define NM_PATH       "/org/freedesktop/NetworkManager"
 #define NM_INTERFACE  NM_SERVICE
@@ -85,6 +87,17 @@ int __connman_iface_store(struct connman_iface *iface);
 int __connman_iface_store_current_network(struct connman_iface *iface);
 int __connman_iface_load_networks(struct connman_iface *iface);
 
+void __connman_iface_network_list(struct connman_iface *iface,
+                                               DBusMessageIter *iter);
+struct connman_network *__connman_iface_find_network(struct connman_iface *iface,
+                                                               const char *path);
+int __connman_iface_remove_network(struct connman_iface *iface, const char *path);
+const char *__connman_iface_add_network(struct connman_iface *iface,
+                               const char *identifier, const char *passphrase);
+
+int __connman_network_init(DBusConnection *conn);
+void __connman_network_cleanup(void);
+
 const char *__connman_iface_type2string(enum connman_iface_type type);
 const char *__connman_iface_state2string(enum connman_iface_state state);
 const char *__connman_iface_policy2string(enum connman_iface_policy policy);
index 29a1eff..2c8ff55 100644 (file)
@@ -284,7 +284,13 @@ int __connman_iface_load_networks(struct connman_iface *iface)
        list = g_key_file_get_string_list(keyfile, GROUP_CONFIG,
                                        "KnownNetworks", &list_len, NULL);
        for (i = 0; i < list_len; i++) {
+               gchar *psk;
+
                DBG("Known network %s", list[i]);
+
+               psk = g_key_file_get_string(keyfile, list[i], "PSK", NULL);
+
+               __connman_iface_add_network(iface, list[i], psk);
        }
 
        g_strfreev(list);
index a29c901..6be7b87 100644 (file)
@@ -863,27 +863,126 @@ static DBusMessage *set_network(DBusConnection *conn,
        return reply;
 }
 
+static DBusMessage *list_networks(DBusConnection *conn,
+                                       DBusMessage *msg, void *data)
+{
+       struct connman_iface *iface = data;
+       DBusMessage *reply;
+       DBusMessageIter array, iter;
+
+       DBG("conn %p", conn);
+
+       reply = dbus_message_new_method_return(msg);
+       if (reply == NULL)
+               return NULL;
+
+       dbus_message_iter_init_append(reply, &array);
+
+       dbus_message_iter_open_container(&array, DBUS_TYPE_ARRAY,
+                               DBUS_TYPE_OBJECT_PATH_AS_STRING, &iter);
+
+       __connman_iface_network_list(iface, &iter);
+
+       dbus_message_iter_close_container(&array, &iter);
+
+       return reply;
+}
+
+static DBusMessage *create_network(DBusConnection *conn,
+                                       DBusMessage *msg, void *data)
+{
+       struct connman_iface *iface = data;
+       DBusMessage *reply;
+       DBusMessageIter array, dict;
+       const char *path, *identifier = NULL, *passphrase = NULL;
+
+       DBG("conn %p", conn);
+
+       dbus_message_iter_init(msg, &array);
+
+       dbus_message_iter_recurse(&array, &dict);
+
+       while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
+               DBusMessageIter entry, value;
+               const char *key, *val;
+
+               dbus_message_iter_recurse(&dict, &entry);
+               dbus_message_iter_get_basic(&entry, &key);
+
+               dbus_message_iter_next(&entry);
+
+               dbus_message_iter_recurse(&entry, &value);
+
+               //type = dbus_message_iter_get_arg_type(&value);
+               dbus_message_iter_get_basic(&value, &val);
+
+               if (g_strcasecmp(key, "Identifier") == 0)
+                       identifier = val;
+
+               if (g_strcasecmp(key, "Passphrase") == 0)
+                       passphrase = val;
+
+               dbus_message_iter_next(&dict);
+       }
+
+       DBG("identifier %s passphrase %s", identifier, passphrase);
+
+       path = __connman_iface_add_network(iface, identifier, passphrase);
+
+       reply = dbus_message_new_method_return(msg);
+       if (reply == NULL)
+               return NULL;
+
+       dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &path,
+                                                       DBUS_TYPE_INVALID);
+
+       return reply;
+}
+
+static DBusMessage *remove_network(DBusConnection *conn,
+                                       DBusMessage *msg, void *data)
+{
+       struct connman_iface *iface = data;
+       DBusMessage *reply;
+       const char *path;
+
+       DBG("conn %p", conn);
+
+       dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
+                                                       DBUS_TYPE_INVALID);
+
+       __connman_iface_remove_network(iface, path);
+
+       reply = dbus_message_new_method_return(msg);
+       if (reply == NULL)
+               return NULL;
+
+       dbus_message_append_args(reply, DBUS_TYPE_INVALID);
+
+       return reply;
+}
+
 static DBusMessage *select_network(DBusConnection *conn,
                                        DBusMessage *msg, void *data)
 {
        struct connman_iface *iface = data;
+       struct connman_network *network;
        DBusMessage *reply;
-       const char *network;
-       gchar *passphrase;
+       const char *path;
 
        DBG("conn %p", conn);
 
-       dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &network,
+       dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
                                                        DBUS_TYPE_INVALID);
 
-       passphrase = __connman_iface_find_passphrase(iface, network);
-       if (passphrase == NULL)
+       network = __connman_iface_find_network(iface, path);
+       if (network == NULL)
                goto done;
 
        g_free(iface->network.identifier);
-       iface->network.identifier = g_strdup(network);
+       iface->network.identifier = g_strdup(network->identifier);
        g_free(iface->network.passphrase);
-       iface->network.passphrase = passphrase;
+       iface->network.passphrase = g_strdup(network->passphrase);
 
        __connman_iface_connect(iface, &iface->network);
 
@@ -1054,7 +1153,10 @@ static GDBusMethodTable iface_methods[] = {
        { "SetPolicy",     "s",     "",      set_policy     },
        { "GetNetwork",    "",      "a{sv}", get_network    },
        { "SetNetwork",    "a{sv}", "",      set_network    },
-       { "SelectNetwork", "s",     "",      select_network },
+       { "ListNetworks",  "",      "ao",    list_networks  },
+       { "CreateNetwork", "a{av}", "o",     create_network },
+       { "RemoveNetwork", "o",     "",      remove_network },
+       { "SelectNetwork", "o",     "",      select_network },
        { "GetIPv4",       "",      "a{sv}", get_ipv4       },
        { "SetIPv4",       "a{sv}", "",      set_ipv4       },
        { },
index e917440..e7d54c2 100644 (file)
@@ -130,8 +130,10 @@ int main(int argc, char *argv[])
        }
 
        if (compat) {
-               if (g_dbus_request_name(conn, NM_SERVICE, NULL) == FALSE)
+               if (g_dbus_request_name(conn, NM_SERVICE, NULL) == FALSE) {
+                       fprintf(stderr, "Can't register compat service\n");
                        compat = 0;
+               }
        }
 
        __connman_log_init(detach, debug);
@@ -144,6 +146,8 @@ int main(int argc, char *argv[])
 
        __connman_rtnl_init();
 
+       __connman_network_init(conn);
+
        __connman_iface_init(conn, interface);
 
        memset(&sa, 0, sizeof(sa));
@@ -155,6 +159,8 @@ int main(int argc, char *argv[])
 
        __connman_iface_cleanup();
 
+       __connman_network_cleanup();
+
        __connman_rtnl_cleanup();
 
        __connman_plugin_cleanup();
index 641bff0..1a080b9 100644 (file)
 #include <config.h>
 #endif
 
+#include <gdbus.h>
+
 #include "connman.h"
+
+static DBusConnection *connection = NULL;
+static unsigned int index = 0;
+
+static GSList *networks = NULL;
+
+void __connman_iface_network_list(struct connman_iface *iface,
+                                               DBusMessageIter *iter)
+{
+       GSList *list;
+
+       DBG("");
+
+       for (list = networks; list; list = list->next) {
+               struct connman_network *network = list->data;
+
+               if (network->iface != iface)
+                       continue;
+
+               dbus_message_iter_append_basic(iter,
+                               DBUS_TYPE_OBJECT_PATH, &network->path);
+       }
+}
+
+struct connman_network *__connman_iface_find_network(struct connman_iface *iface,
+                                                               const char *path)
+{
+       GSList *list;
+
+       DBG("");
+
+       for (list = networks; list; list = list->next) {
+               struct connman_network *network = list->data;
+
+               if (network->iface == iface &&
+                               g_str_equal(network->path, path) == TRUE)
+                       return network;
+       }
+
+       return NULL;
+}
+
+int __connman_iface_remove_network(struct connman_iface *iface, const char *path)
+{
+       g_dbus_unregister_object(connection, path);
+
+       return 0;
+}
+
+static DBusMessage *get_identifier(DBusConnection *conn,
+                                       DBusMessage *msg, void *data)
+{
+       struct connman_network *network = data;
+       DBusMessage *reply;
+
+       DBG("conn %p", conn);
+
+       reply = dbus_message_new_method_return(msg);
+       if (reply == NULL)
+               return NULL;
+
+       dbus_message_append_args(reply, DBUS_TYPE_STRING, &network->identifier,
+                                                       DBUS_TYPE_INVALID);
+
+       return reply;
+}
+
+static DBusMessage *get_passphrase(DBusConnection *conn,
+                                       DBusMessage *msg, void *data)
+{
+       struct connman_network *network = data;
+       DBusMessage *reply;
+
+       DBG("conn %p", conn);
+
+       reply = dbus_message_new_method_return(msg);
+       if (reply == NULL)
+               return NULL;
+
+       dbus_message_append_args(reply, DBUS_TYPE_STRING, &network->passphrase,
+                                                       DBUS_TYPE_INVALID);
+
+       return reply;
+}
+
+static GDBusMethodTable network_methods[] = {
+       { "GetIdentifier", "", "s", get_identifier },
+       { "GetPassphrase", "", "s", get_passphrase },
+       { },
+};
+
+static void network_free(void *data)
+{
+       struct connman_network *network = data;
+
+       DBG("");
+
+       networks = g_slist_remove(networks, network);
+
+       g_free(network->path);
+       g_free(network->identifier);
+       g_free(network->passphrase);
+       g_free(network);
+}
+
+const char *__connman_iface_add_network(struct connman_iface *iface,
+                               const char *identifier, const char *passphrase)
+{
+       struct connman_network *network;
+       gchar *path;
+
+       DBG("iface %p", iface);
+
+       network = g_try_new0(struct connman_network, 1);
+       if (network == NULL)
+               return NULL;
+
+       path = g_strdup_printf("%s/net_%d", iface->path, index++);
+       if (path == NULL) {
+               g_free(network);
+               return NULL;
+       }
+
+       network->iface = iface;
+
+       network->path = path;
+       network->identifier = g_strdup(identifier);
+       network->passphrase = g_strdup(passphrase ? passphrase : "");
+
+       networks = g_slist_append(networks, network);
+
+       g_dbus_register_object(connection, path, network, network_free);
+
+       g_dbus_register_interface(connection, path, CONNMAN_NETWORK_INTERFACE,
+                                               network_methods, NULL, NULL);
+
+       return path;
+}
+
+int __connman_network_init(DBusConnection *conn)
+{
+       DBG("conn %p", conn);
+
+       connection = dbus_connection_ref(conn);
+       if (connection == NULL)
+               return -1;
+
+       return 0;
+}
+
+void __connman_network_cleanup(void)
+{
+       DBG("conn %p", connection);
+
+       dbus_connection_unref(connection);
+}