Include interface name in statistics usage
authorMarcel Holtmann <marcel@holtmann.org>
Tue, 5 Jan 2010 15:29:49 +0000 (07:29 -0800)
committerMarcel Holtmann <marcel@holtmann.org>
Tue, 5 Jan 2010 15:29:49 +0000 (07:29 -0800)
src/connman.h
src/counter.c
src/ipconfig.c
test/test-counter

index 0537bf0..cc3bd08 100644 (file)
@@ -69,7 +69,8 @@ int __connman_counter_register(const char *owner, const char *path,
                                                unsigned int interval);
 int __connman_counter_unregister(const char *owner, const char *path);
 
-void __connman_counter_notify(unsigned int rx_bytes, unsigned int tx_bytes);
+void __connman_counter_notify(const char *interface,
+                               unsigned int rx_bytes, unsigned int tx_bytes);
 
 int __connman_counter_init(void);
 void __connman_counter_cleanup(void);
index 7c213b6..19259c7 100644 (file)
 
 static DBusConnection *connection;
 
+static GHashTable *stats_table;
 static GHashTable *counter_table;
 static GHashTable *owner_mapping;
 
+struct connman_stats {
+       char *interface;
+       unsigned int rx_bytes;
+       unsigned int tx_bytes;
+};
+
 struct connman_counter {
        char *owner;
        char *path;
        guint timeout;
        guint watch;
-       unsigned int rx_bytes;
-       unsigned int tx_bytes;
 };
 
+static void remove_stats(gpointer user_data)
+{
+       struct connman_stats *stats = user_data;
+
+       g_free(stats->interface);
+       g_free(stats);
+}
+
 static void remove_counter(gpointer user_data)
 {
        struct connman_counter *counter = user_data;
@@ -133,7 +146,8 @@ int __connman_counter_unregister(const char *owner, const char *path)
        return 0;
 }
 
-static void send_usage(struct connman_counter *counter)
+static void send_usage(struct connman_counter *counter, const char *interface,
+                               unsigned int rx_bytes, unsigned int tx_bytes)
 {
        DBusMessage *message;
        DBusMessageIter array, dict;
@@ -149,34 +163,51 @@ static void send_usage(struct connman_counter *counter)
 
        connman_dbus_dict_open(&array, &dict);
 
+       connman_dbus_dict_append_basic(&dict, "Interface",
+                                               DBUS_TYPE_STRING, &interface);
        connman_dbus_dict_append_basic(&dict, "RX.Bytes",
-                                       DBUS_TYPE_UINT32, &counter->rx_bytes);
+                                               DBUS_TYPE_UINT32, &rx_bytes);
        connman_dbus_dict_append_basic(&dict, "TX.Bytes",
-                                       DBUS_TYPE_UINT32, &counter->tx_bytes);
+                                               DBUS_TYPE_UINT32, &tx_bytes);
 
        connman_dbus_dict_close(&array, &dict);
 
        g_dbus_send_message(connection, message);
 }
 
-void __connman_counter_notify(unsigned int rx_bytes, unsigned int tx_bytes)
+void __connman_counter_notify(const char *interface,
+                               unsigned int rx_bytes, unsigned int tx_bytes)
 {
+       struct connman_stats *stats;
        GHashTableIter iter;
        gpointer key, value;
 
+       stats = g_hash_table_lookup(stats_table, interface);
+       if (stats != NULL)
+               goto update;
+
+       stats = g_try_new0(struct connman_stats, 1);
+       if (stats == NULL)
+               return;
+
+       stats->interface = g_strdup(interface);
+
+       g_hash_table_replace(stats_table, stats->interface, stats);
+
+update:
+       if (stats->rx_bytes == rx_bytes && stats->rx_bytes == tx_bytes)
+               return;
+
+       stats->rx_bytes = rx_bytes;
+       stats->tx_bytes = tx_bytes;
+
        g_hash_table_iter_init(&iter, counter_table);
 
        while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
                struct connman_counter *counter = value;
 
-               if (counter->rx_bytes == rx_bytes &&
-                                       counter->tx_bytes == tx_bytes)
-                       continue;
-
-               counter->rx_bytes = rx_bytes;
-               counter->tx_bytes = tx_bytes;
-
-               send_usage(counter);
+               send_usage(counter, stats->interface,
+                                       stats->rx_bytes, stats->tx_bytes);
        }
 }
 
@@ -205,6 +236,9 @@ int __connman_counter_init(void)
        if (connection == NULL)
                return -1;
 
+       stats_table = g_hash_table_new_full(g_str_hash, g_str_equal,
+                                                       NULL, remove_stats);
+
        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,
@@ -225,5 +259,7 @@ void __connman_counter_cleanup(void)
        g_hash_table_destroy(owner_mapping);
        g_hash_table_destroy(counter_table);
 
+       g_hash_table_destroy(stats_table);
+
        dbus_connection_unref(connection);
 }
index 0d0426e..38c317b 100644 (file)
@@ -357,7 +357,8 @@ static void update_stats(struct connman_ipdevice *ipdevice,
        ipdevice->rx_bytes = stats->rx_bytes;
        ipdevice->tx_bytes = stats->tx_bytes;
 
-       __connman_counter_notify(ipdevice->rx_bytes, ipdevice->tx_bytes);
+       __connman_counter_notify(ipdevice->ifname,
+                               ipdevice->rx_bytes, ipdevice->tx_bytes);
 }
 
 void __connman_ipconfig_newlink(int index, unsigned short type,
index d000a8d..6a42885 100755 (executable)
@@ -17,7 +17,10 @@ class Counter(dbus.service.Object):
                                        in_signature='a{sv}', out_signature='')
        def Usage(self, stats):
                for key in stats.keys():
-                       val = int(stats[key])
+                       if key in ["Interface"]:
+                               val = str(stats[key])
+                       else:
+                               val = int(stats[key])
                        print "%s = %s" % (key, val)
 
 if __name__ == '__main__':