summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.am4
-rw-r--r--doc/manager-api.txt12
-rw-r--r--include/dbus.h1
-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
-rwxr-xr-xtest/test-counter36
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);
+}
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 },
{ },
};
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)