*
* Connection Manager
*
- * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2012 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
#include <config.h>
#endif
+#include <errno.h>
+
#include <gdbus.h>
#include "connman.h"
static DBusConnection *connection;
-static GHashTable *stats_table;
static GHashTable *counter_table;
static GHashTable *owner_mapping;
guint watch;
};
-struct counter_data {
- struct connman_service *service;
- connman_bool_t first_update;
-};
-
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);
-
__connman_rtnl_update_interval_remove(counter->interval);
+ __connman_service_counter_unregister(counter->path);
+
g_free(counter->owner);
g_free(counter->path);
g_free(counter);
}
-static void remove_data(gpointer user_data)
-{
- struct counter_data *data = user_data;
-
- g_free(data);
-}
-
static void owner_disconnect(DBusConnection *connection, void *user_data)
{
struct connman_counter *counter = user_data;
unsigned int interval)
{
struct connman_counter *counter;
+ int err;
DBG("owner %s path %s interval %u", owner, path, interval);
counter->owner = g_strdup(owner);
counter->path = g_strdup(path);
+ err = __connman_service_counter_register(counter->path);
+ if (err < 0) {
+ g_free(counter->owner);
+ g_free(counter->path);
+ g_free(counter);
+ return err;
+ }
+
g_hash_table_replace(counter_table, counter->path, counter);
g_hash_table_replace(owner_mapping, counter->owner, counter);
if (g_strcmp0(owner, counter->owner) != 0)
return -EACCES;
+ if (counter->watch > 0)
+ g_dbus_remove_watch(connection, counter->watch);
+
g_hash_table_remove(owner_mapping, counter->owner);
g_hash_table_remove(counter_table, counter->path);
return 0;
}
-static void send_usage(struct connman_counter *counter,
- struct connman_service *service)
+void __connman_counter_send_usage(const char *path,
+ DBusMessage *message)
{
- DBusMessage *message;
- DBusMessageIter array, dict;
- const char *service_path;
- unsigned long rx_bytes;
- unsigned long tx_bytes;
- unsigned long time;
+ struct connman_counter *counter;
- message = dbus_message_new_method_call(counter->owner, counter->path,
- CONNMAN_COUNTER_INTERFACE, "Usage");
- if (message == NULL)
+ counter = g_hash_table_lookup(counter_table, path);
+ if (counter == NULL)
return;
+ dbus_message_set_destination(message, counter->owner);
+ dbus_message_set_path(message, counter->path);
+ dbus_message_set_interface(message, CONNMAN_COUNTER_INTERFACE);
+ dbus_message_set_member(message, "Usage");
dbus_message_set_no_reply(message, TRUE);
- service_path = __connman_service_get_path(service);
- dbus_message_append_args(message, DBUS_TYPE_OBJECT_PATH,
- &service_path, DBUS_TYPE_INVALID);
-
- dbus_message_iter_init_append(message, &array);
-
- connman_dbus_dict_open(&array, &dict);
-
- rx_bytes = __connman_service_stats_get_rx_bytes(service);
- tx_bytes = __connman_service_stats_get_tx_bytes(service);
- time = __connman_service_stats_get_time(service);
-
- connman_dbus_dict_append_basic(&dict, "RX.Bytes", DBUS_TYPE_UINT32,
- &rx_bytes);
- connman_dbus_dict_append_basic(&dict, "TX.Bytes", DBUS_TYPE_UINT32,
- &tx_bytes);
- connman_dbus_dict_append_basic(&dict, "Time", DBUS_TYPE_UINT32,
- &time);
-
- connman_dbus_dict_close(&array, &dict);
-
g_dbus_send_message(connection, message);
}
-void __connman_counter_notify(struct connman_ipconfig *config,
- unsigned int rx_bytes, unsigned int tx_bytes)
-{
- struct counter_data *data;
- GHashTableIter iter;
- gpointer key, value;
-
- data = g_hash_table_lookup(stats_table, config);
- if (data == NULL)
- return;
-
- __connman_service_stats_update(data->service, rx_bytes, tx_bytes);
-
- if (data->first_update == TRUE) {
- data->first_update = FALSE;
- return;
- }
-
- g_hash_table_iter_init(&iter, counter_table);
- while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
- struct connman_counter *counter = value;
-
- send_usage(counter, data->service);
- }
-}
-
static void release_counter(gpointer key, gpointer value, gpointer user_data)
{
struct connman_counter *counter = value;
DBG("owner %s path %s", counter->owner, counter->path);
+ if (counter->watch > 0)
+ g_dbus_remove_watch(connection, counter->watch);
+
message = dbus_message_new_method_call(counter->owner, counter->path,
CONNMAN_COUNTER_INTERFACE, "Release");
if (message == NULL)
g_dbus_send_message(connection, message);
}
-int __connman_counter_add_service(struct connman_service *service)
-{
- struct connman_ipconfig *config;
- struct counter_data *data;
-
- data = g_try_new0(struct counter_data, 1);
- if (data == NULL)
- return -ENOMEM;
-
- data->service = service;
- data->first_update = TRUE;
-
- config = __connman_service_get_ipconfig(service);
- g_hash_table_replace(stats_table, config, data);
-
- /*
- * Trigger a first update to intialize the offset counters
- * in the service.
- */
- __connman_rtnl_request_update();
-
- return 0;
-}
-
-void __connman_counter_remove_service(struct connman_service *service)
-{
- struct connman_ipconfig *config;
-
- config = __connman_service_get_ipconfig(service);
- g_hash_table_remove(stats_table, config);
-}
-
int __connman_counter_init(void)
{
DBG("");
if (connection == NULL)
return -1;
- stats_table = g_hash_table_new_full(g_direct_hash, g_str_equal,
- NULL, remove_data);
-
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,
g_hash_table_destroy(owner_mapping);
g_hash_table_destroy(counter_table);
- g_hash_table_destroy(stats_table);
-
dbus_connection_unref(connection);
}