manager: Add hooks for the PrivateNetwork API
authorGustavo F. Padovan <padovan@profusion.mobi>
Wed, 20 Apr 2011 12:41:19 +0000 (14:41 +0200)
committerSamuel Ortiz <sameo@linux.intel.com>
Wed, 20 Apr 2011 13:18:56 +0000 (15:18 +0200)
RequestPrivateNetwork() doesn't return an fd yet and
both of them are completely dummy.

src/connman.h
src/manager.c
src/tethering.c

index f80d16f..ab2b52e 100644 (file)
@@ -456,6 +456,9 @@ void __connman_tethering_update_interface(const char *interface);
 void __connman_tethering_set_enabled(void);
 void __connman_tethering_set_disabled(void);
 
+int __connman_private_network_request(const char *owner);
+int __connman_private_network_release(const char *owner);
+
 #include <connman/provider.h>
 
 void __connman_provider_append_properties(struct connman_provider *provider, DBusMessageIter *iter);
index 4afed26..0514655 100644 (file)
@@ -591,6 +591,40 @@ static DBusMessage *destroy_session(DBusConnection *conn,
        return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
 }
 
+static DBusMessage *request_private_network(DBusConnection *conn,
+                                       DBusMessage *msg, void *data)
+{
+       const char *sender;
+       int  err;
+
+       DBG("conn %p", conn);
+
+       sender = dbus_message_get_sender(msg);
+
+       err = __connman_private_network_request(sender);
+       if (err < 0)
+               return __connman_error_failed(msg, -err);
+
+       return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
+}
+
+static DBusMessage *release_private_network(DBusConnection *conn,
+                                       DBusMessage *msg, void *data)
+{
+       const char *sender;
+       int err;
+
+       DBG("conn %p", conn);
+
+       sender = dbus_message_get_sender(msg);
+
+       err = __connman_private_network_release(sender);
+       if (err < 0)
+               return __connman_error_failed(msg, -err);
+
+       return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
+}
+
 static GDBusMethodTable manager_methods[] = {
        { "GetProperties",     "",      "a{sv}", get_properties     },
        { "SetProperty",       "sv",    "",      set_property       },
@@ -615,6 +649,10 @@ static GDBusMethodTable manager_methods[] = {
        { "UnregisterCounter", "o",     "",      unregister_counter },
        { "CreateSession",     "a{sv}o", "o",    create_session     },
        { "DestroySession",    "o",     "",      destroy_session    },
+       { "RequestPrivateNetwork",    "",     "",
+                                               request_private_network },
+       { "ReleasePrivateNetwork",    "",     "",
+                                               release_private_network },
        { },
 };
 
index 27f4b0d..00fa3de 100644 (file)
@@ -35,6 +35,8 @@
 
 #include <gdhcp/gdhcp.h>
 
+#include <gdbus.h>
+
 #define BRIDGE_PROC_DIR "/proc/sys/net/bridge"
 
 #define BRIDGE_NAME "tether"
 static char *default_interface = NULL;
 static volatile gint tethering_enabled;
 static GDHCPServer *tethering_dhcp_server = NULL;
+static DBusConnection *connection;
+static GHashTable *pn_hash;
+
+struct connman_private_network {
+       char *owner;
+       guint watch;
+};
 
 const char *__connman_tethering_get_bridge(void)
 {
@@ -368,12 +377,76 @@ void __connman_tethering_update_interface(const char *interface)
        enable_nat(interface);
 }
 
+static void remove_private_network(gpointer user_data)
+{
+       struct connman_private_network *pn = user_data;
+
+       if (pn->watch > 0) {
+               g_dbus_remove_watch(connection, pn->watch);
+               pn->watch = 0;
+       }
+
+       g_free(pn->owner);
+       g_free(pn);
+}
+
+static void owner_disconnect(DBusConnection *connection, void *user_data)
+{
+       struct connman_private_network *pn = user_data;
+
+       DBG("%s died", pn->owner);
+
+       pn->watch = 0;
+
+       g_hash_table_remove(pn_hash, pn->owner);
+}
+
+int __connman_private_network_request(const char *owner)
+{
+       struct connman_private_network *pn;
+
+       pn = g_hash_table_lookup(pn_hash, owner);
+       if (pn != NULL)
+               return -EEXIST;
+
+       pn = g_try_new0(struct connman_private_network, 1);
+       if (pn == NULL)
+               return -ENOMEM;
+
+       pn->owner = g_strdup(owner);
+       pn->watch = g_dbus_add_disconnect_watch(connection, pn->owner,
+                                       owner_disconnect, pn, NULL);
+
+       g_hash_table_insert(pn_hash, pn->owner, pn);
+
+       return 0;
+}
+
+int __connman_private_network_release(const char *owner)
+{
+       struct connman_private_network *pn;
+
+       pn = g_hash_table_lookup(pn_hash, owner);
+       if (pn == NULL)
+               return -EACCES;
+
+       g_hash_table_remove(pn_hash, owner);
+       return 0;
+}
+
 int __connman_tethering_init(void)
 {
        DBG("");
 
        tethering_enabled = 0;
 
+       connection = connman_dbus_get_connection();
+       if (connection == NULL)
+               return -EFAULT;
+
+       pn_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
+                                               NULL, remove_private_network);
+
        return 0;
 }
 
@@ -387,4 +460,10 @@ void __connman_tethering_cleanup(void)
                disable_bridge(BRIDGE_NAME);
                remove_bridge(BRIDGE_NAME);
        }
+
+       if (connection == NULL)
+               return;
+
+       g_hash_table_destroy(pn_hash);
+       dbus_connection_unref(connection);
 }