diff options
-rw-r--r-- | Makefile.am | 4 | ||||
-rw-r--r-- | doc/manager-api.txt | 12 | ||||
-rw-r--r-- | include/dbus.h | 1 | ||||
-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 | ||||
-rwxr-xr-x | test/test-counter | 36 |
9 files changed, 288 insertions, 2 deletions
diff --git a/Makefile.am b/Makefile.am index 2b1b87db..99f1fb16 100644 --- a/Makefile.am +++ b/Makefile.am @@ -52,7 +52,7 @@ src_connmand_SOURCES = $(gdbus_sources) $(builtin_sources) \ src/ipv4.c src/dhcp.c src/rtnl.c src/inet.c \ src/utsname.c src/timeserver.c src/rfkill.c \ src/wifi.c src/storage.c src/dbus.c src/config.c \ - src/technology.c + src/technology.c src/counter.c if UDEV src_connmand_SOURCES += src/udev.c @@ -137,7 +137,7 @@ test_scripts = test/get-state test/list-profiles test/list-services \ test/simple-agent test/show-introspection test/test-compat \ test/test-manager test/test-connman test/monitor-connman \ test/connect-vpn test/disconnect-vpn test/list-providers \ - test/monitor-manager + test/monitor-manager test/test-counter if TEST testdir = $(pkglibdir)/test diff --git a/doc/manager-api.txt b/doc/manager-api.txt index a50b4ef4..35477dc3 100644 --- a/doc/manager-api.txt +++ b/doc/manager-api.txt @@ -105,6 +105,18 @@ Methods dict GetProperties() Possible Errors: [service].Error.InvalidArguments + void RegisterCounter(object path, uint32 interval) + + Register a new counter for user notifications. + + Possible Errors: [service].Error.InvalidArguments + + void UnregisterCounter(object path) + + Unregister an existing counter. + + Possible Errors: [service].Error.InvalidArguments + Signals PropertyChanged(string name, variant value) This signal indicates a changed value of the given diff --git a/include/dbus.h b/include/dbus.h index 73bda693..36629dfb 100644 --- a/include/dbus.h +++ b/include/dbus.h @@ -33,6 +33,7 @@ extern "C" { #define CONNMAN_DEBUG_INTERFACE CONNMAN_SERVICE ".Debug" #define CONNMAN_ERROR_INTERFACE CONNMAN_SERVICE ".Error" #define CONNMAN_AGENT_INTERFACE CONNMAN_SERVICE ".Agent" +#define CONNMAN_COUNTER_INTERFACE CONNMAN_SERVICE ".Counter" #define CONNMAN_MANAGER_INTERFACE CONNMAN_SERVICE ".Manager" #define CONNMAN_MANAGER_PATH "/" 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 }, { }, }; diff --git a/test/test-counter b/test/test-counter new file mode 100755 index 00000000..b0173a4a --- /dev/null +++ b/test/test-counter @@ -0,0 +1,36 @@ +#!/usr/bin/python + +import gobject + +import dbus +import dbus.service +import dbus.mainloop.glib + +class Counter(dbus.service.Object): + @dbus.service.method("org.moblin.connman.Counter", + in_signature='', out_signature='') + def Release(self): + print("Release") + mainloop.quit() + + @dbus.service.method("org.moblin.connman.Counter", + in_signature='', out_signature='') + def Usage(self): + print("Usage") + +if __name__ == '__main__': + dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) + + bus = dbus.SystemBus() + manager = dbus.Interface(bus.get_object('org.moblin.connman', "/"), + 'org.moblin.connman.Manager') + + path = "/test/counter" + object = Counter(bus, path) + + manager.RegisterCounter(path, dbus.UInt32(2)) + + mainloop = gobject.MainLoop() + mainloop.run() + + #manager.UnregisterCounter(path) |