tethering: Update APIs to be able to use multiple private networks
authorGuillaume Zajac <guillaume.zajac@linux.intel.com>
Tue, 28 Jun 2011 13:19:12 +0000 (15:19 +0200)
committerSamuel Ortiz <sameo@linux.intel.com>
Thu, 30 Jun 2011 09:59:58 +0000 (11:59 +0200)
src/connman.h
src/manager.c
src/tethering.c

index 0c6d6b1..e4c35da 100644 (file)
@@ -435,7 +435,7 @@ void __connman_tethering_set_enabled(void);
 void __connman_tethering_set_disabled(void);
 
 int __connman_private_network_request(DBusMessage *msg, const char *owner);
-int __connman_private_network_release(const char *owner);
+int __connman_private_network_release(const char *path);
 
 #include <connman/provider.h>
 
index e883364..722d621 100644 (file)
@@ -613,14 +613,15 @@ static DBusMessage *request_private_network(DBusConnection *conn,
 static DBusMessage *release_private_network(DBusConnection *conn,
                                        DBusMessage *msg, void *data)
 {
-       const char *sender;
+       const char *path;
        int err;
 
        DBG("conn %p", conn);
 
-       sender = dbus_message_get_sender(msg);
+       dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
+                                                       DBUS_TYPE_INVALID);
 
-       err = __connman_private_network_release(sender);
+       err = __connman_private_network_release(path);
        if (err < 0)
                return __connman_error_failed(msg, -err);
 
@@ -651,10 +652,10 @@ static GDBusMethodTable manager_methods[] = {
        { "UnregisterCounter", "o",     "",      unregister_counter },
        { "CreateSession",     "a{sv}o", "o",    create_session     },
        { "DestroySession",    "o",     "",      destroy_session    },
-       { "RequestPrivateNetwork",    "",     "ha{sv}",
+       { "RequestPrivateNetwork",    "",     "oa{sv}h",
                                                request_private_network,
                                                G_DBUS_METHOD_FLAG_ASYNC },
-       { "ReleasePrivateNetwork",    "",     "",
+       { "ReleasePrivateNetwork",    "o",    "",
                                                release_private_network },
        { },
 };
index fbb9e77..0357530 100644 (file)
@@ -72,6 +72,7 @@ static GHashTable *pn_hash;
 
 struct connman_private_network {
        char *owner;
+       char *path;
        guint watch;
        DBusMessage *msg;
        DBusMessage *reply;
@@ -420,7 +421,6 @@ static void setup_tun_interface(unsigned int flags, unsigned change,
 {
        struct connman_private_network *pn = data;
        unsigned char prefixlen;
-       DBusMessage *reply;
        DBusMessageIter array, dict;
        int err;
 
@@ -448,56 +448,54 @@ static void setup_tun_interface(unsigned int flags, unsigned change,
                goto error;
        }
 
-       reply = dbus_message_new_method_return(pn->msg);
-
-       if (reply == NULL)
-               goto error;
-
-       dbus_message_iter_init_append(reply, &array);
+       dbus_message_iter_init_append(pn->reply, &array);
 
-       dbus_message_iter_append_basic(&array, DBUS_TYPE_UNIX_FD, &pn->fd);
+       dbus_message_iter_append_basic(&array, DBUS_TYPE_OBJECT_PATH,
+                                               &pn->path);
 
        connman_dbus_dict_open(&array, &dict);
 
        connman_dbus_dict_append_basic(&dict, "ServerIPv4",
-                                               DBUS_TYPE_STRING, &pn->server_ip);
+                                       DBUS_TYPE_STRING, &pn->server_ip);
        connman_dbus_dict_append_basic(&dict, "PeerIPv4",
-                                               DBUS_TYPE_STRING, &pn->peer_ip);
+                                       DBUS_TYPE_STRING, &pn->peer_ip);
        connman_dbus_dict_append_basic(&dict, "PrimaryDNS",
-                                               DBUS_TYPE_STRING, &pn->primary_dns);
+                                       DBUS_TYPE_STRING, &pn->primary_dns);
        connman_dbus_dict_append_basic(&dict, "SecondaryDNS",
-                                               DBUS_TYPE_STRING, &pn->secondary_dns);
+                                       DBUS_TYPE_STRING, &pn->secondary_dns);
 
        connman_dbus_dict_close(&array, &dict);
 
-       g_dbus_send_message(connection, reply);
+       dbus_message_iter_append_basic(&array, DBUS_TYPE_UNIX_FD, &pn->fd);
+
+       g_dbus_send_message(connection, pn->reply);
 
        return;
 
 error:
-       reply = __connman_error_failed(pn->msg, -err);
-       g_dbus_send_message(connection, reply);
+       pn->reply = __connman_error_failed(pn->msg, -err);
+       g_dbus_send_message(connection, pn->reply);
 
-       g_hash_table_remove(pn_hash, pn->owner);
+       g_hash_table_remove(pn_hash, pn->path);
 }
 
 static void remove_private_network(gpointer user_data)
 {
        struct connman_private_network *pn = user_data;
 
-       close(pn->fd);
-
-       connman_rtnl_remove_watch(pn->iface_watch);
-
        disable_nat(default_interface);
+       connman_rtnl_remove_watch(pn->iface_watch);
 
        if (pn->watch > 0) {
                g_dbus_remove_watch(connection, pn->watch);
                pn->watch = 0;
        }
 
+       close(pn->fd);
+
        g_free(pn->interface);
        g_free(pn->owner);
+       g_free(pn->path);
        g_free(pn);
 }
 
@@ -509,26 +507,33 @@ static void owner_disconnect(DBusConnection *connection, void *user_data)
 
        pn->watch = 0;
 
-       g_hash_table_remove(pn_hash, pn->owner);
+       g_hash_table_remove(pn_hash, pn->path);
 }
 
 int __connman_private_network_request(DBusMessage *msg, const char *owner)
 {
        struct connman_private_network *pn;
        char *iface = NULL;
+       char *path = NULL;
        int index, fd, err;
 
        if (DBUS_TYPE_UNIX_FD < 0)
                return -EINVAL;
 
-       pn = g_hash_table_lookup(pn_hash, owner);
-       if (pn != NULL)
-               return -EEXIST;
-
        fd = connman_inet_create_tunnel(&iface);
        if (fd < 0)
                return fd;
 
+       path = g_strdup_printf("/tethering/%s", iface);
+
+       pn = g_hash_table_lookup(pn_hash, path);
+       if (pn) {
+               g_free(path);
+               g_free(iface);
+               close(fd);
+               return -EEXIST;
+       }
+
        index = connman_inet_ifindex(iface);
        if (index < 0) {
                err = -ENODEV;
@@ -545,9 +550,14 @@ int __connman_private_network_request(DBusMessage *msg, const char *owner)
        }
 
        pn->owner = g_strdup(owner);
+       pn->path = path;
        pn->watch = g_dbus_add_disconnect_watch(connection, pn->owner,
                                        owner_disconnect, pn, NULL);
        pn->msg = msg;
+       pn->reply = dbus_message_new_method_return(pn->msg);
+       if (pn->reply == NULL)
+               goto error;
+
        pn->fd = fd;
        pn->interface = iface;
        pn->index = index;
@@ -559,25 +569,27 @@ int __connman_private_network_request(DBusMessage *msg, const char *owner)
        pn->iface_watch = connman_rtnl_add_newlink_watch(index,
                                                setup_tun_interface, pn);
 
-       g_hash_table_insert(pn_hash, pn->owner, pn);
+       g_hash_table_insert(pn_hash, pn->path, pn);
 
        return 0;
 
 error:
        close(fd);
        g_free(iface);
+       g_free(path);
+       g_free(pn);
        return err;
 }
 
-int __connman_private_network_release(const char *owner)
+int __connman_private_network_release(const char *path)
 {
        struct connman_private_network *pn;
 
-       pn = g_hash_table_lookup(pn_hash, owner);
+       pn = g_hash_table_lookup(pn_hash, path);
        if (pn == NULL)
                return -EACCES;
 
-       g_hash_table_remove(pn_hash, owner);
+       g_hash_table_remove(pn_hash, path);
        return 0;
 }