summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuillaume Zajac <guillaume.zajac@linux.intel.com>2011-06-28 15:19:12 +0200
committerSamuel Ortiz <sameo@linux.intel.com>2011-06-30 11:59:58 +0200
commitea81b3269f9f507a6be8d139662e1c1d387e9417 (patch)
tree2ec62973f8b408153505e0753cc62149da99f6aa
parentc8106a94a3369a98e9eafba941beb84773156f7c (diff)
downloadconnman-ea81b3269f9f507a6be8d139662e1c1d387e9417.tar.gz
connman-ea81b3269f9f507a6be8d139662e1c1d387e9417.tar.bz2
connman-ea81b3269f9f507a6be8d139662e1c1d387e9417.zip
tethering: Update APIs to be able to use multiple private networks
-rw-r--r--src/connman.h2
-rw-r--r--src/manager.c11
-rw-r--r--src/tethering.c70
3 files changed, 48 insertions, 35 deletions
diff --git a/src/connman.h b/src/connman.h
index 0c6d6b1c..e4c35da5 100644
--- a/src/connman.h
+++ b/src/connman.h
@@ -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>
diff --git a/src/manager.c b/src/manager.c
index e8833646..722d6216 100644
--- a/src/manager.c
+++ b/src/manager.c
@@ -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 },
{ },
};
diff --git a/src/tethering.c b/src/tethering.c
index fbb9e77f..0357530d 100644
--- a/src/tethering.c
+++ b/src/tethering.c
@@ -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;
}