From 55e275762c011595ed1d106bbb3867be415a8a07 Mon Sep 17 00:00:00 2001 From: "Gustavo F. Padovan" Date: Wed, 20 Apr 2011 14:41:19 +0200 Subject: [PATCH] manager: Add hooks for the PrivateNetwork API RequestPrivateNetwork() doesn't return an fd yet and both of them are completely dummy. --- src/connman.h | 3 +++ src/manager.c | 38 +++++++++++++++++++++++++++ src/tethering.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 120 insertions(+) diff --git a/src/connman.h b/src/connman.h index f80d16f..ab2b52e 100644 --- a/src/connman.h +++ b/src/connman.h @@ -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 void __connman_provider_append_properties(struct connman_provider *provider, DBusMessageIter *iter); diff --git a/src/manager.c b/src/manager.c index 4afed26..0514655 100644 --- a/src/manager.c +++ b/src/manager.c @@ -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 }, { }, }; diff --git a/src/tethering.c b/src/tethering.c index 27f4b0d..00fa3de 100644 --- a/src/tethering.c +++ b/src/tethering.c @@ -35,6 +35,8 @@ #include +#include + #define BRIDGE_PROC_DIR "/proc/sys/net/bridge" #define BRIDGE_NAME "tether" @@ -48,6 +50,13 @@ 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); } -- 2.7.4