diff options
author | Marcel Holtmann <marcel@holtmann.org> | 2010-01-04 22:42:45 -0800 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2010-01-04 22:42:45 -0800 |
commit | 29b2c9556ff6965d3b688e2ff6483dd8ffd43519 (patch) | |
tree | f2ee081afe198b86658f893ef27b6eebf666d163 /src | |
parent | 65afea87023cc3e3cec215c6f2f0fa1f1e250040 (diff) | |
download | connman-29b2c9556ff6965d3b688e2ff6483dd8ffd43519.tar.gz connman-29b2c9556ff6965d3b688e2ff6483dd8ffd43519.tar.bz2 connman-29b2c9556ff6965d3b688e2ff6483dd8ffd43519.zip |
Add framework for counter callbacks
Diffstat (limited to 'src')
-rw-r--r-- | src/connman-dbus.conf | 1 | ||||
-rw-r--r-- | src/connman.h | 7 | ||||
-rw-r--r-- | src/counter.c | 183 | ||||
-rw-r--r-- | src/main.c | 2 | ||||
-rw-r--r-- | src/manager.c | 44 |
5 files changed, 237 insertions, 0 deletions
diff --git a/src/connman-dbus.conf b/src/connman-dbus.conf index 2be37645..345b87e4 100644 --- a/src/connman-dbus.conf +++ b/src/connman-dbus.conf @@ -5,6 +5,7 @@ <allow own="org.moblin.connman"/> <allow send_destination="org.moblin.connman"/> <allow send_interface="org.moblin.connman.Agent"/> + <allow send_interface="org.moblin.connman.Counter"/> </policy> <policy user="system"> <allow send_destination="org.moblin.connman"/> diff --git a/src/connman.h b/src/connman.h index 61dd4119..6f6b6215 100644 --- a/src/connman.h +++ b/src/connman.h @@ -65,6 +65,13 @@ void __connman_agent_cleanup(void); int __connman_agent_register(const char *sender, const char *path); int __connman_agent_unregister(const char *sender, const char *path); +int __connman_counter_register(const char *owner, const char *path, + unsigned int interval); +int __connman_counter_unregister(const char *owner, const char *path); + +int __connman_counter_init(void); +void __connman_counter_cleanup(void); + struct connman_service; typedef void (* passphrase_cb_t) (struct connman_service *service, diff --git a/src/counter.c b/src/counter.c new file mode 100644 index 00000000..9dea4b7e --- /dev/null +++ b/src/counter.c @@ -0,0 +1,183 @@ +/* + * + * Connection Manager + * + * Copyright (C) 2007-2010 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <gdbus.h> + +#include "connman.h" + +static DBusConnection *connection; + +static GHashTable *counter_table; +static GHashTable *owner_mapping; + +struct connman_counter { + char *owner; + char *path; + guint timeout; + guint watch; +}; + +static void remove_counter(gpointer user_data) +{ + struct connman_counter *counter = user_data; + + DBG("owner %s path %s", counter->owner, counter->path); + + if (counter->watch > 0) + g_dbus_remove_watch(connection, counter->watch); + + if (counter->timeout > 0) + g_source_remove(counter->timeout); + + g_free(counter->owner); + g_free(counter->path); + g_free(counter); +} + +static void owner_disconnect(DBusConnection *connection, void *user_data) +{ + struct connman_counter *counter = user_data; + + DBG("owner %s path %s", counter->owner, counter->path); + + g_hash_table_remove(owner_mapping, counter->owner); + g_hash_table_remove(counter_table, counter->path); +} + +static gboolean counter_timeout(gpointer user_data) +{ + struct connman_counter *counter = user_data; + DBusMessage *message; + + DBG("owner %s path %s", counter->owner, counter->path); + + message = dbus_message_new_method_call(counter->owner, counter->path, + CONNMAN_COUNTER_INTERFACE, "Usage"); + if (message == NULL) + return TRUE; + + dbus_message_set_no_reply(message, TRUE); + + g_dbus_send_message(connection, message); + + return TRUE; +} + +int __connman_counter_register(const char *owner, const char *path, + unsigned int interval) +{ + struct connman_counter *counter; + + DBG("owner %s path %s interval %u", owner, path, interval); + + counter = g_hash_table_lookup(counter_table, path); + if (counter != NULL) + return -EEXIST; + + counter = g_try_new0(struct connman_counter, 1); + if (counter == NULL) + return -ENOMEM; + + counter->owner = g_strdup(owner); + counter->path = g_strdup(path); + + g_hash_table_replace(counter_table, counter->path, counter); + g_hash_table_replace(owner_mapping, counter->owner, counter); + + counter->timeout = g_timeout_add_seconds(interval, + counter_timeout, counter); + + counter->watch = g_dbus_add_disconnect_watch(connection, owner, + owner_disconnect, counter, NULL); + + return 0; +} + +int __connman_counter_unregister(const char *owner, const char *path) +{ + struct connman_counter *counter; + + DBG("owner %s path %s", owner, path); + + counter = g_hash_table_lookup(counter_table, path); + if (counter == NULL) + return -ESRCH; + + if (g_strcmp0(owner, counter->owner) != 0) + return -EACCES; + + g_hash_table_remove(owner_mapping, counter->owner); + g_hash_table_remove(counter_table, counter->path); + + return 0; +} + +static void release_counter(gpointer key, gpointer value, gpointer user_data) +{ + struct connman_counter *counter = value; + DBusMessage *message; + + DBG("owner %s path %s", counter->owner, counter->path); + + message = dbus_message_new_method_call(counter->owner, counter->path, + CONNMAN_COUNTER_INTERFACE, "Release"); + if (message == NULL) + return; + + dbus_message_set_no_reply(message, TRUE); + + g_dbus_send_message(connection, message); +} + +int __connman_counter_init(void) +{ + DBG(""); + + connection = connman_dbus_get_connection(); + if (connection == NULL) + return -1; + + counter_table = g_hash_table_new_full(g_str_hash, g_str_equal, + NULL, remove_counter); + owner_mapping = g_hash_table_new_full(g_str_hash, g_str_equal, + NULL, NULL); + + return 0; +} + +void __connman_counter_cleanup(void) +{ + DBG(""); + + if (connection == NULL) + return; + + g_hash_table_foreach(counter_table, release_counter, NULL); + + g_hash_table_destroy(owner_mapping); + g_hash_table_destroy(counter_table); + + dbus_connection_unref(connection); +} @@ -207,6 +207,7 @@ int main(int argc, char *argv[]) __connman_element_init(option_device, option_nodevice); __connman_agent_init(); + __connman_counter_init(); __connman_manager_init(option_compat); __connman_profile_init(); __connman_config_init(); @@ -246,6 +247,7 @@ int main(int argc, char *argv[]) __connman_config_cleanup(); __connman_profile_cleanup(); __connman_manager_cleanup(); + __connman_counter_cleanup(); __connman_agent_cleanup(); __connman_element_cleanup(); diff --git a/src/manager.c b/src/manager.c index b10dd3dc..cc5d163d 100644 --- a/src/manager.c +++ b/src/manager.c @@ -504,6 +504,48 @@ static DBusMessage *unregister_agent(DBusConnection *conn, return g_dbus_create_reply(msg, DBUS_TYPE_INVALID); } +static DBusMessage *register_counter(DBusConnection *conn, + DBusMessage *msg, void *data) +{ + const char *sender, *path; + unsigned int interval; + 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_UINT32, &interval, + DBUS_TYPE_INVALID); + + err = __connman_counter_register(sender, path, interval); + if (err < 0) + return __connman_error_failed(msg, -err); + + return g_dbus_create_reply(msg, DBUS_TYPE_INVALID); +} + +static DBusMessage *unregister_counter(DBusConnection *conn, + DBusMessage *msg, void *data) +{ + const char *sender, *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_counter_unregister(sender, path); + 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 }, @@ -522,6 +564,8 @@ static GDBusMethodTable manager_methods[] = { G_DBUS_METHOD_FLAG_ASYNC }, { "RegisterAgent", "o", "", register_agent }, { "UnregisterAgent", "o", "", unregister_agent }, + { "RegisterCounter", "ou", "", register_counter }, + { "UnregisterCounter", "o", "", unregister_counter }, { }, }; |