From: Daniel Wagner <[email protected]>

Currently connman only has one set of counters for
collecting statistics on online time and
the amount of transfered bytes.

For 3G connections we should destinguish between
home network and roaming. This patch introduces
two sets of counter values for home network
and roaming network.
---
The juicy part is still missing (__connman_service_roaming), the 
rest should be in place

v1: - Rebase to head
    - Use two dictionaries home and roaming in Usage() as descriped in 
documentationw
    - Remove test-connman patch leftovers
v0: - initial version
    - The Counter API should be done and is ready for review. 
    - The inner logic is still missing.

 src/connman.h     |   15 +--
 src/counter.c     |   54 ++------
 src/service.c     |  382 ++++++++++++++++++++++++++++++++++++++---------------
 test/test-counter |   11 +-
 4 files changed, 302 insertions(+), 160 deletions(-)

diff --git a/src/connman.h b/src/connman.h
index 7482d5b..b758bd6 100644
--- a/src/connman.h
+++ b/src/connman.h
@@ -452,15 +452,12 @@ void __connman_service_nameserver_add_routes(struct 
connman_service *service,
                                                const char *gw);
 void __connman_service_nameserver_del_routes(struct connman_service *service);
 
-unsigned long __connman_service_stats_get_rx_packets(struct connman_service 
*service);
-unsigned long __connman_service_stats_get_tx_packets(struct connman_service 
*service);
-unsigned long __connman_service_stats_get_rx_bytes(struct connman_service 
*service);
-unsigned long __connman_service_stats_get_tx_bytes(struct connman_service 
*service);
-unsigned long __connman_service_stats_get_rx_errors(struct connman_service 
*service);
-unsigned long __connman_service_stats_get_tx_errors(struct connman_service 
*service);
-unsigned long __connman_service_stats_get_rx_dropped(struct connman_service 
*service);
-unsigned long __connman_service_stats_get_tx_dropped(struct connman_service 
*service);
-unsigned long __connman_service_stats_get_time(struct connman_service 
*service);
+void __connman_service_stats_home_append(struct connman_service *service,
+                                               DBusMessageIter *dict,
+                                               connman_bool_t append_all);
+void __connman_service_stats_roaming_append(struct connman_service *service,
+                                               DBusMessageIter *dict,
+                                               connman_bool_t append_all);
 void __connman_service_stats_update(struct connman_service *service,
                                unsigned int rx_packets, unsigned int 
tx_packets,
                                unsigned int rx_bytes, unsigned int tx_bytes,
diff --git a/src/counter.c b/src/counter.c
index 27898c5..747c6bf 100644
--- a/src/counter.c
+++ b/src/counter.c
@@ -38,6 +38,7 @@ struct connman_counter {
        char *path;
        unsigned int interval;
        guint watch;
+       connman_bool_t first_update;
 };
 
 struct counter_data {
@@ -95,6 +96,7 @@ int __connman_counter_register(const char *owner, const char 
*path,
 
        counter->owner = g_strdup(owner);
        counter->path = g_strdup(path);
+       counter->first_update = TRUE;
 
        g_hash_table_replace(counter_table, counter->path, counter);
        g_hash_table_replace(owner_mapping, counter->owner, counter);
@@ -128,20 +130,11 @@ int __connman_counter_unregister(const char *owner, const 
char *path)
 }
 
 static void send_usage(struct connman_counter *counter,
-                               struct connman_service *service)
+                               struct counter_data *data)
 {
-       DBusMessage *message;
        DBusMessageIter array, dict;
+       DBusMessage *message;
        const char *service_path;
-       unsigned long rx_packets;
-       unsigned long tx_packets;
-       unsigned long rx_bytes;
-       unsigned long tx_bytes;
-       unsigned long rx_errors;
-       unsigned long tx_errors;
-       unsigned long rx_dropped;
-       unsigned long tx_dropped;
-       unsigned long time;
 
        message = dbus_message_new_method_call(counter->owner, counter->path,
                                        CONNMAN_COUNTER_INTERFACE, "Usage");
@@ -150,7 +143,7 @@ static void send_usage(struct connman_counter *counter,
 
        dbus_message_set_no_reply(message, TRUE);
 
-       service_path = __connman_service_get_path(service);
+       service_path = __connman_service_get_path(data->service);
        dbus_message_append_args(message, DBUS_TYPE_OBJECT_PATH,
                                        &service_path, DBUS_TYPE_INVALID);
 
@@ -159,42 +152,21 @@ static void send_usage(struct connman_counter *counter,
        /* home counter */
        connman_dbus_dict_open(&array, &dict);
 
-       rx_packets = __connman_service_stats_get_rx_packets(service);
-       tx_packets = __connman_service_stats_get_tx_packets(service);
-       rx_bytes = __connman_service_stats_get_rx_bytes(service);
-       tx_bytes = __connman_service_stats_get_tx_bytes(service);
-       rx_errors = __connman_service_stats_get_rx_errors(service);
-       tx_errors = __connman_service_stats_get_tx_errors(service);
-       rx_dropped = __connman_service_stats_get_rx_dropped(service);
-       tx_dropped = __connman_service_stats_get_tx_dropped(service);
-       time = __connman_service_stats_get_time(service);
-
-       connman_dbus_dict_append_basic(&dict, "RX.Packets", DBUS_TYPE_UINT32,
-                               &rx_packets);
-       connman_dbus_dict_append_basic(&dict, "TX.Packets", DBUS_TYPE_UINT32,
-                               &tx_packets);
-       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, "RX.Errors", DBUS_TYPE_UINT32,
-                               &rx_errors);
-       connman_dbus_dict_append_basic(&dict, "TX.Errors", DBUS_TYPE_UINT32,
-                               &tx_errors);
-       connman_dbus_dict_append_basic(&dict, "RX.Dropped", DBUS_TYPE_UINT32,
-                               &rx_dropped);
-       connman_dbus_dict_append_basic(&dict, "TX.Dropped", DBUS_TYPE_UINT32,
-                               &tx_dropped);
-       connman_dbus_dict_append_basic(&dict, "Time", DBUS_TYPE_UINT32,
-                               &time);
+       __connman_service_stats_home_append(data->service, &dict,
+                                       counter->first_update);
 
        connman_dbus_dict_close(&array, &dict);
 
        /* roaming counter */
        connman_dbus_dict_open(&array, &dict);
 
+       __connman_service_stats_roaming_append(data->service, &dict,
+                                       counter->first_update);
+
        connman_dbus_dict_close(&array, &dict);
 
+       counter->first_update = FALSE;
+
        g_dbus_send_message(connection, message);
 }
 
@@ -227,7 +199,7 @@ void __connman_counter_notify(struct connman_ipconfig 
*config,
        while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
                struct connman_counter *counter = value;
 
-               send_usage(counter, data->service);
+               send_usage(counter, data);
        }
 }
 
diff --git a/src/service.c b/src/service.c
index bf2400a..31b483a 100644
--- a/src/service.c
+++ b/src/service.c
@@ -39,23 +39,32 @@ static GHashTable *service_hash = NULL;
 struct connman_stats {
        connman_bool_t valid;
        connman_bool_t enabled;
+       unsigned int rx_packets_update;
+       unsigned int tx_packets_update;
        unsigned int rx_packets_last;
        unsigned int tx_packets_last;
        unsigned int rx_packets;
        unsigned int tx_packets;
+       unsigned int rx_bytes_update;
+       unsigned int tx_bytes_update;
        unsigned int rx_bytes_last;
        unsigned int tx_bytes_last;
        unsigned int rx_bytes;
        unsigned int tx_bytes;
+       unsigned int rx_errors_update;
+       unsigned int tx_errors_update;
        unsigned int rx_errors_last;
        unsigned int tx_errors_last;
        unsigned int rx_errors;
        unsigned int tx_errors;
+       unsigned int rx_dropped_update;
+       unsigned int tx_dropped_update;
        unsigned int rx_dropped_last;
        unsigned int tx_dropped_last;
        unsigned int rx_dropped;
        unsigned int tx_dropped;
        unsigned int time_start;
+       unsigned int time_update;
        unsigned int time;
        GTimer *timer;
 };
@@ -104,6 +113,7 @@ struct connman_service {
        guint timeout;
        struct connman_location *location;
        struct connman_stats stats;
+       struct connman_stats stats_roaming;
 };
 
 static void append_path(gpointer value, gpointer user_data)
@@ -424,24 +434,39 @@ void __connman_service_nameserver_del_routes(struct 
connman_service *service)
        }
 }
 
+static connman_bool_t __connman_service_roaming(struct connman_service 
*service)
+{
+       return FALSE;
+}
+
+static struct connman_stats *__connman_service_get_stats(struct 
connman_service *service)
+{
+       if (__connman_service_roaming(service))
+               return &service->stats_roaming;
+       else
+               return &service->stats;
+}
+
 static void __connman_service_stats_start(struct connman_service *service)
 {
+       struct connman_stats *stats = __connman_service_get_stats(service);
+
        DBG("service %p", service);
 
-       if (service->stats.timer == NULL)
+       if (stats->timer == NULL)
                return;
 
-       service->stats.enabled = TRUE;
-
-       service->stats.time_start = service->stats.time;
+       stats->enabled = TRUE;
+       stats->time_start = stats->time;
 
-       g_timer_start(service->stats.timer);
+       g_timer_start(stats->timer);
 
        __connman_counter_add_service(service);
 }
 
 static void __connman_service_stats_stop(struct connman_service *service)
 {
+       struct connman_stats *stats = __connman_service_get_stats(service);
        unsigned int seconds;
 
        DBG("service %p", service);
@@ -454,126 +479,136 @@ static void __connman_service_stats_stop(struct 
connman_service *service)
 
        __connman_counter_remove_service(service);
 
-       g_timer_stop(service->stats.timer);
+       g_timer_stop(stats->timer);
 
-       seconds = g_timer_elapsed(service->stats.timer, NULL);
-       service->stats.time = service->stats.time_start + seconds;
+       seconds = g_timer_elapsed(stats->timer, NULL);
+       stats->time = stats->time_start + seconds;
 
-       service->stats.enabled = FALSE;
+       stats->enabled = FALSE;
 }
 
-static int __connman_service_stats_load(struct connman_service *service,
-               GKeyFile *keyfile, const char *identifier)
+static int __connman_service_stats_load(struct connman_stats *stats,
+               GKeyFile *keyfile, const char *identifier, const char *prefix)
 {
-       service->stats.rx_packets = g_key_file_get_integer(keyfile,
-                               identifier, "rx_packets", NULL);
-       service->stats.tx_packets = g_key_file_get_integer(keyfile,
-                               identifier, "tx_packets", NULL);
-       service->stats.rx_bytes = g_key_file_get_integer(keyfile,
-                               identifier, "rx_bytes", NULL);
-       service->stats.tx_bytes = g_key_file_get_integer(keyfile,
-                               identifier, "tx_bytes", NULL);
-       service->stats.rx_errors = g_key_file_get_integer(keyfile,
-                               identifier, "rx_errors", NULL);
-       service->stats.tx_errors = g_key_file_get_integer(keyfile,
-                               identifier, "tx_errors", NULL);
-       service->stats.rx_dropped = g_key_file_get_integer(keyfile,
-                               identifier, "rx_dropped", NULL);
-       service->stats.tx_dropped = g_key_file_get_integer(keyfile,
-                               identifier, "tx_dropped", NULL);
-       service->stats.time = g_key_file_get_integer(keyfile,
-                               identifier, "time", NULL);
+       char *key;
 
-       return 0;
-}
+       key = g_strdup_printf("%srx_packets", prefix);
+       stats->rx_packets = g_key_file_get_integer(keyfile,
+                               identifier, key, NULL);
+       g_free(key);
+
+       key = g_strdup_printf("%stx_packets", prefix);
+       stats->tx_packets = g_key_file_get_integer(keyfile,
+                               identifier, key, NULL);
+       g_free(key);
+
+       key = g_strdup_printf("%srx_bytes", prefix);
+       stats->rx_bytes = g_key_file_get_integer(keyfile,
+                               identifier, key, NULL);
+       g_free(key);
+
+       key = g_strdup_printf("%stx_bytes", prefix);
+       stats->tx_bytes = g_key_file_get_integer(keyfile,
+                               identifier, key, NULL);
+       g_free(key);
+
+       key = g_strdup_printf("%srx_errors", prefix);
+       stats->rx_errors = g_key_file_get_integer(keyfile,
+                               identifier, key, NULL);
+       g_free(key);
+
+       key = g_strdup_printf("%stx_errors", prefix);
+       stats->tx_errors = g_key_file_get_integer(keyfile,
+                               identifier, key, NULL);
+       g_free(key);
+
+       key = g_strdup_printf("%srx_dropped", prefix);
+       stats->rx_dropped = g_key_file_get_integer(keyfile,
+                               identifier, key, NULL);
+       g_free(key);
+
+       key = g_strdup_printf("%stx_dropped", prefix);
+       stats->tx_dropped = g_key_file_get_integer(keyfile,
+                               identifier, key, NULL);
+       g_free(key);
 
-static int __connman_service_stats_save(struct connman_service *service,
-               GKeyFile *keyfile, const char *identifier)
-{
-       g_key_file_set_integer(keyfile, identifier, "rx_packets",
-                       service->stats.rx_packets);
-       g_key_file_set_integer(keyfile, identifier, "tx_packets",
-                       service->stats.tx_packets);
-       g_key_file_set_integer(keyfile, identifier, "rx_bytes",
-                       service->stats.rx_bytes);
-       g_key_file_set_integer(keyfile, identifier, "tx_bytes",
-                       service->stats.tx_bytes);
-       g_key_file_set_integer(keyfile, identifier, "rx_errors",
-                       service->stats.rx_errors);
-       g_key_file_set_integer(keyfile, identifier, "tx_errors",
-                       service->stats.tx_errors);
-       g_key_file_set_integer(keyfile, identifier, "rx_dropped",
-                       service->stats.rx_dropped);
-       g_key_file_set_integer(keyfile, identifier, "tx_dropped",
-                       service->stats.tx_dropped);
-       g_key_file_set_integer(keyfile, identifier, "time",
-                       service->stats.time);
+       key = g_strdup_printf("%stime", prefix);
+       stats->time = g_key_file_get_integer(keyfile,
+                               identifier, key, NULL);
+       g_free(key);
 
        return 0;
 }
 
-static void __connman_service_reset_stats(struct connman_service *service)
+static int __connman_service_stats_save(struct connman_stats *stats,
+               GKeyFile *keyfile, const char *identifier, const char *prefix)
 {
-       DBG("service %p", service);
+       char *key;
 
-       service->stats.valid = FALSE;
-       service->stats.rx_packets = 0;
-       service->stats.tx_packets = 0;
-       service->stats.rx_bytes = 0;
-       service->stats.tx_bytes = 0;
-       service->stats.rx_errors = 0;
-       service->stats.tx_errors = 0;
-       service->stats.rx_dropped = 0;
-       service->stats.tx_dropped = 0;
-       service->stats.time = 0;
-       service->stats.time_start = 0;
-       g_timer_reset(service->stats.timer);
+       key = g_strdup_printf("%srx_packets", prefix);
+       g_key_file_set_integer(keyfile, identifier, key,
+                       stats->rx_packets);
+       g_free(key);
 
-}
+       key = g_strdup_printf("%stx_packets", prefix);
+       g_key_file_set_integer(keyfile, identifier, key,
+                       stats->tx_packets);
+       g_free(key);
 
-unsigned long __connman_service_stats_get_rx_packets(struct connman_service 
*service)
-{
-       return service->stats.rx_packets;
-}
+       key = g_strdup_printf("%srx_bytes", prefix);
+       g_key_file_set_integer(keyfile, identifier, key,
+                       stats->rx_bytes);
+       g_free(key);
 
-unsigned long __connman_service_stats_get_tx_packets(struct connman_service 
*service)
-{
-       return service->stats.tx_packets;
-}
+       key = g_strdup_printf("%stx_bytes", prefix);
+       g_key_file_set_integer(keyfile, identifier, key,
+                       stats->tx_bytes);
+       g_free(key);
 
-unsigned long __connman_service_stats_get_rx_bytes(struct connman_service 
*service)
-{
-       return service->stats.rx_bytes;
-}
+       key = g_strdup_printf("%srx_errors", prefix);
+       g_key_file_set_integer(keyfile, identifier, key,
+                       stats->rx_errors);
+       g_free(key);
 
-unsigned long __connman_service_stats_get_tx_bytes(struct connman_service 
*service)
-{
-       return service->stats.tx_bytes;
-}
+       key = g_strdup_printf("%stx_errors", prefix);
+       g_key_file_set_integer(keyfile, identifier, key,
+                       stats->tx_errors);
+       g_free(key);
 
-unsigned long __connman_service_stats_get_rx_errors(struct connman_service 
*service)
-{
-       return service->stats.rx_errors;
-}
+       key = g_strdup_printf("%srx_dropped", prefix);
+       g_key_file_set_integer(keyfile, identifier, key,
+                       stats->rx_dropped);
+       g_free(key);
 
-unsigned long __connman_service_stats_get_tx_errors(struct connman_service 
*service)
-{
-       return service->stats.tx_errors;
-}
+       key = g_strdup_printf("%stx_dropped", prefix);
+       g_key_file_set_integer(keyfile, identifier, key,
+                       stats->tx_dropped);
+       g_free(key);
 
-unsigned long __connman_service_stats_get_rx_dropped(struct connman_service 
*service)
-{
-       return service->stats.rx_dropped;
-}
+       key = g_strdup_printf("%stime", prefix);
+       g_key_file_set_integer(keyfile, identifier, key,
+                       stats->time);
+       g_free(key);
 
-unsigned long __connman_service_stats_get_tx_dropped(struct connman_service 
*service)
-{
-       return service->stats.tx_dropped;
+       return 0;
 }
 
-unsigned long __connman_service_stats_get_time(struct connman_service *service)
+static void __connman_service_reset_stats(struct connman_stats *stats)
 {
-       return service->stats.time;
+       DBG("stats %p", stats);
+
+       stats->valid = FALSE;
+       stats->rx_packets = 0;
+       stats->tx_packets = 0;
+       stats->rx_bytes = 0;
+       stats->tx_bytes = 0;
+       stats->rx_errors = 0;
+       stats->tx_errors = 0;
+       stats->rx_dropped = 0;
+       stats->tx_dropped = 0;
+       stats->time = 0;
+       stats->time_start = 0;
+       g_timer_reset(stats->timer);
 }
 
 static struct connman_service *get_default(void)
@@ -896,6 +931,122 @@ static void domain_configuration_changed(struct 
connman_service *service)
                                DBUS_TYPE_STRING, append_domainconfig, service);
 }
 
+static void append_all_stats(DBusMessageIter *dict, struct connman_stats 
*stats)
+{
+       stats->rx_packets_update = stats->rx_packets;
+       connman_dbus_dict_append_basic(dict, "RX.Packets", DBUS_TYPE_UINT32,
+                               &stats->rx_packets);
+
+       stats->tx_packets_update = stats->tx_packets;
+       connman_dbus_dict_append_basic(dict, "TX.Packets", DBUS_TYPE_UINT32,
+                               &stats->tx_packets);
+
+       stats->rx_bytes_update = stats->rx_bytes;
+       connman_dbus_dict_append_basic(dict, "RX.Bytes", DBUS_TYPE_UINT32,
+                                       &stats->rx_bytes);
+
+       stats->tx_bytes_update = stats->tx_bytes;
+       connman_dbus_dict_append_basic(dict, "TX.Bytes", DBUS_TYPE_UINT32,
+                                       &stats->tx_bytes);
+
+       stats->rx_errors_update = stats->rx_errors;
+       connman_dbus_dict_append_basic(dict, "RX.Errors", DBUS_TYPE_UINT32,
+                               &stats->rx_errors);
+
+       stats->tx_errors_update = stats->tx_errors;
+       connman_dbus_dict_append_basic(dict, "TX.Errors", DBUS_TYPE_UINT32,
+                               &stats->tx_errors);
+
+       stats->rx_dropped_update = stats->rx_dropped;
+       connman_dbus_dict_append_basic(dict, "RX.Dropped", DBUS_TYPE_UINT32,
+                               &stats->rx_dropped);
+
+       stats->tx_dropped_update = stats->tx_dropped;
+       connman_dbus_dict_append_basic(dict, "TX.Dropped", DBUS_TYPE_UINT32,
+                               &stats->tx_dropped);
+
+       stats->time_update = stats->time;
+       connman_dbus_dict_append_basic(dict, "Time", DBUS_TYPE_UINT32,
+                               &stats->time);
+}
+
+static void append_stats(DBusMessageIter *dict, struct connman_stats *stats)
+{
+       if (stats->rx_packets_update != stats->rx_packets) {
+               stats->rx_packets_update = stats->rx_packets;
+               connman_dbus_dict_append_basic(dict, "RX.Packets",
+                                       DBUS_TYPE_UINT32, &stats->rx_packets);
+       }
+
+       if (stats->tx_packets_update != stats->tx_packets) {
+               stats->tx_packets_update = stats->tx_packets;
+               connman_dbus_dict_append_basic(dict, "TX.Packets",
+                                       DBUS_TYPE_UINT32, &stats->tx_packets);
+       }
+
+       if (stats->rx_bytes_update != stats->rx_bytes) {
+               stats->rx_bytes_update = stats->rx_bytes;
+               connman_dbus_dict_append_basic(dict, "RX.Bytes",
+                                       DBUS_TYPE_UINT32, &stats->rx_bytes);
+       }
+
+       if (stats->tx_bytes_update != stats->tx_bytes) {
+               stats->tx_bytes_update = stats->tx_bytes;
+               connman_dbus_dict_append_basic(dict, "TX.Bytes",
+                                       DBUS_TYPE_UINT32, &stats->tx_bytes);
+       }
+
+       if (stats->rx_errors_update != stats->rx_errors) {
+               stats->rx_errors_update = stats->rx_errors;
+               connman_dbus_dict_append_basic(dict, "RX.Errors",
+                                       DBUS_TYPE_UINT32, &stats->rx_errors);
+       }
+
+       if (stats->tx_errors_update != stats->tx_errors) {
+               stats->tx_errors_update = stats->tx_errors;
+               connman_dbus_dict_append_basic(dict, "TX.Errors",
+                                       DBUS_TYPE_UINT32, &stats->tx_errors);
+       }
+
+       if (stats->rx_dropped_update != stats->rx_dropped) {
+               stats->rx_dropped_update = stats->rx_dropped;
+               connman_dbus_dict_append_basic(dict, "RX.Dropped",
+                                       DBUS_TYPE_UINT32, &stats->rx_dropped);
+       }
+
+       if (stats->tx_dropped_update != stats->tx_dropped) {
+               stats->tx_dropped_update = stats->tx_dropped;
+               connman_dbus_dict_append_basic(dict, "TX.Dropped",
+                                       DBUS_TYPE_UINT32, &stats->tx_dropped);
+       }
+
+       if (stats->time_update != stats->time) {
+               stats->time_update = stats->time;
+               connman_dbus_dict_append_basic(dict, "Time",
+                                       DBUS_TYPE_UINT32, &stats->time);
+       }
+}
+
+void __connman_service_stats_home_append(struct connman_service *service,
+                                               DBusMessageIter *dict,
+                                               connman_bool_t append_all)
+{
+       if (append_all == TRUE)
+               append_all_stats(dict, &service->stats);
+       else
+               append_stats(dict, &service->stats);
+}
+
+void __connman_service_stats_roaming_append(struct connman_service *service,
+                                               DBusMessageIter *dict,
+                                               connman_bool_t append_all)
+{
+       if (append_all == TRUE)
+               append_all_stats(dict, &service->stats_roaming);
+       else
+               append_stats(dict, &service->stats_roaming);
+}
+
 static void append_properties(DBusMessageIter *dict, dbus_bool_t limited,
                                        struct connman_service *service)
 {
@@ -1779,7 +1930,8 @@ static DBusMessage *reset_stats(DBusConnection *conn,
 {
        struct connman_service *service = user_data;
 
-       __connman_service_reset_stats(service);
+       __connman_service_reset_stats(&service->stats);
+       __connman_service_reset_stats(&service->stats_roaming);
 
        return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
 }
@@ -1861,6 +2013,8 @@ static void service_free(gpointer user_data)
 
        if (service->stats.timer != NULL)
                g_timer_destroy(service->stats.timer);
+       if (service->stats_roaming.timer != NULL)
+               g_timer_destroy(service->stats_roaming.timer);
 
        g_free(service);
 }
@@ -1890,6 +2044,13 @@ void __connman_service_put(struct connman_service 
*service)
        }
 }
 
+static void __connman_stats_init(struct connman_stats *stats)
+{
+       stats->valid = FALSE;
+       stats->enabled = FALSE;
+       stats->timer = g_timer_new();
+}
+
 static void __connman_service_initialize(struct connman_service *service)
 {
        DBG("service %p", service);
@@ -1911,9 +2072,8 @@ static void __connman_service_initialize(struct 
connman_service *service)
 
        service->order = 0;
 
-       service->stats.valid = FALSE;
-       service->stats.enabled = FALSE;
-       service->stats.timer = g_timer_new();
+       __connman_stats_init(&service->stats);
+       __connman_stats_init(&service->stats_roaming);
 }
 
 /**
@@ -2770,6 +2930,7 @@ static void service_up(struct connman_ipconfig *ipconfig)
        connman_info("%s up", connman_ipconfig_get_ifname(ipconfig));
 
        service->stats.valid = FALSE;
+       service->stats_roaming.valid = FALSE;
 }
 
 static void service_down(struct connman_ipconfig *ipconfig)
@@ -3223,7 +3384,7 @@ void __connman_service_stats_update(struct 
connman_service *service,
                                unsigned int rx_dropped, unsigned int 
tx_dropped)
 {
        unsigned int seconds;
-       struct connman_stats *stats = &service->stats;
+       struct connman_stats *stats = __connman_service_get_stats(service);
 
        DBG("service %p", service);
 
@@ -3421,7 +3582,11 @@ static int service_load(struct connman_service *service)
                service->domains = NULL;
        }
 
-       __connman_service_stats_load(service, keyfile, service->identifier);
+       __connman_service_stats_load(&service->stats_roaming, keyfile,
+                               service->identifier, "Roaming.");
+       __connman_service_stats_load(&service->stats, keyfile,
+                               service->identifier, "Home.");
+
 done:
        g_key_file_free(keyfile);
 
@@ -3575,7 +3740,10 @@ update:
                g_key_file_remove_key(keyfile, service->identifier,
                                                        "Domains", NULL);
 
-       __connman_service_stats_save(service, keyfile, service->identifier);
+       __connman_service_stats_save(&service->stats_roaming, keyfile,
+                               service->identifier, "Roaming.");
+       __connman_service_stats_save(&service->stats, keyfile,
+                               service->identifier, "Home.");
 
        data = g_key_file_to_data(keyfile, &length, NULL);
 
diff --git a/test/test-counter b/test/test-counter
index 2cdee34..1e9acf0 100755
--- a/test/test-counter
+++ b/test/test-counter
@@ -29,7 +29,7 @@ def print_stats(stats):
 
        for key in keys:
                val = int(stats[key])
-               str = "  %s = %s" % (key, val)
+               str = "    %s = %s" % (key, val)
 
                if key in ["RX.Bytes", "TX.Bytes"]:
                        hstr = make_bytes_readable(val)
@@ -49,8 +49,13 @@ class Counter(dbus.service.Object):
                                in_signature='oa{sv}a{sv}', out_signature='')
        def Usage(self, path, home, roaming):
                print "%s" % (path)
-               print_stats(home)
-               print_stats(roaming)
+
+               if len(home) > 0:
+                       print "  Home"
+                       print_stats(home)
+               if len(roaming) > 0:
+                       print "  Roaming"
+                       print_stats(roaming)
 
 if __name__ == '__main__':
        dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
-- 
1.7.1.1

_______________________________________________
connman mailing list
[email protected]
http://lists.connman.net/listinfo/connman

Reply via email to