summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2010-01-04 22:42:45 -0800
committerMarcel Holtmann <marcel@holtmann.org>2010-01-04 22:42:45 -0800
commit29b2c9556ff6965d3b688e2ff6483dd8ffd43519 (patch)
treef2ee081afe198b86658f893ef27b6eebf666d163 /src
parent65afea87023cc3e3cec215c6f2f0fa1f1e250040 (diff)
downloadconnman-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.conf1
-rw-r--r--src/connman.h7
-rw-r--r--src/counter.c183
-rw-r--r--src/main.c2
-rw-r--r--src/manager.c44
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);
+}
diff --git a/src/main.c b/src/main.c
index c8b4389e..aef6d1b4 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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 },
{ },
};