Add a number of iteration for updating device list
[platform/core/connectivity/net-config.git] / src / network-statistics.c
1 /*
2  * Network Configuration Module
3  *
4  * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19
20 #include <stdio.h>
21 #include <vconf.h>
22 #include <vconf-keys.h>
23
24 #include "log.h"
25 #include "util.h"
26 #include "netsupplicant.h"
27 #include "network-state.h"
28 #include "network-statistics.h"
29
30 #include "generated-code.h"
31
32 #define NETCONFIG_PROCDEV                                       "/proc/net/dev"
33
34 static Network_statistics *netconfigstatistics = NULL;
35
36 static wifi_device_data_s *__find_wifi_interface_name(const char *interface_name)
37 {
38         GSList *list = wifi_state_get_device_list();
39
40         for ( ; list; list = list->next) {
41                 wifi_device_data_s *device_data = list->data;
42                 if (g_strcmp0(device_data->interface_name, interface_name) == 0)
43                         return device_data;
44         }
45
46         return NULL;
47 }
48
49 gboolean netconfig_wifi_get_bytes_statistics(guint64 *tx, guint64 *rx, gboolean update)
50 {
51         gboolean ret = FALSE;
52         FILE *fp;
53         gchar buf[1024];
54         gchar *p_ifname = NULL, *p_entry = NULL;
55         guint64 curr_tx = 0;
56         guint64 curr_rx = 0;
57         wifi_device_data_s *device_data = NULL;
58
59         *tx = 0;
60         *rx = 0;
61
62         fp = fopen(NETCONFIG_PROCDEV, "r");
63         if (fp == NULL) {
64                 ERR("Failed to open %s", NETCONFIG_PROCDEV);
65                 return FALSE;
66         }
67
68         /* skip the first and second line */
69         if (fgets(buf, sizeof(buf), fp) == NULL ||
70                         fgets(buf, sizeof(buf), fp) == NULL)
71                 goto endline;
72
73         while (fgets(buf, sizeof(buf), fp)) {
74                 long long unsigned int llval;
75                 gulong lval;
76
77                 p_ifname = buf;
78                 while (*p_ifname == ' ') p_ifname++;
79                 p_entry = strchr(p_ifname, ':');
80                 if (p_entry == NULL)
81                         continue;
82
83                 *p_entry++ = '\0';
84
85                 device_data = __find_wifi_interface_name(p_ifname);
86                 if (device_data == NULL)
87                         continue;
88
89                 /* read interface statistics */
90                 sscanf(p_entry,
91                                 "%llu %llu %lu %lu %lu %lu %lu %lu "
92                                 "%llu %llu %lu %lu %lu %lu %lu %lu",
93                                 (long long unsigned int *)&curr_rx, /* rx bytes */
94                                 &llval,         /* rx packet */
95                                 &lval,          /* rx errors */
96                                 &lval,          /* rx dropped */
97                                 &lval,          /* rx fifo errors */
98                                 &lval,          /* rx frame errors */
99                                 &lval,          /* rx compressed */
100                                 &lval,          /* rx multicast */
101
102                                 (long long unsigned int *)&curr_tx, /* tx bytes */
103                                 &llval,         /* tx packet */
104                                 &lval,          /* tx errors */
105                                 &lval,          /* tx dropped */
106                                 &lval,          /* tx fifo errors */
107                                 &lval,          /* collisions */
108                                 &lval,          /* tx carrier errors */
109                                 &lval           /* tx compressed */
110                                 );
111
112                 if (update == TRUE) {
113                         device_data->tx_diff = curr_tx - device_data->tx;
114                         device_data->rx_diff = curr_rx - device_data->rx;
115                         device_data->tx = curr_tx;
116                         device_data->rx = curr_rx;
117                 }
118
119                 *tx += device_data->tx_diff;
120                 *rx += device_data->rx_diff;
121
122                 ret = TRUE;
123         }
124
125 endline:
126         fclose(fp);
127         return ret;
128 }
129
130 void netconfig_wifi_get_bytes_default_iface(guint64 *tx, guint64 *rx)
131 {
132         wifi_device_data_s *device_data = NULL;
133
134         *tx = 0;
135         *rx = 0;
136
137         device_data = __find_wifi_interface_name(netconfig_get_default_ifname());
138         if (device_data == NULL)
139                 return;
140
141         *tx = device_data->tx_diff;
142         *rx = device_data->rx_diff;
143 }
144
145 void netconfig_wifi_set_bytes_pkt_vconf(guint64 tx_diff, guint64 rx_diff)
146 {
147         int val = 0;
148         guint64 last_tx = 0, last_rx = 0;
149         guint64 total_tx = 0, total_rx = 0;
150
151         /* LAST */
152         netconfig_vconf_get_int(VCONFKEY_NETWORK_WIFI_PKT_LAST_SNT, &val);
153         last_tx = (guint64)val + tx_diff;
154
155         netconfig_vconf_get_int(VCONFKEY_NETWORK_WIFI_PKT_LAST_RCV, &val);
156         last_rx = (guint64)val + rx_diff;
157
158         netconfig_set_vconf_int(VCONFKEY_NETWORK_WIFI_PKT_LAST_SNT, (int)last_tx, FALSE);
159         netconfig_set_vconf_int(VCONFKEY_NETWORK_WIFI_PKT_LAST_RCV, (int)last_rx, FALSE);
160
161         /* TOTAL */
162         netconfig_vconf_get_int(VCONFKEY_NETWORK_WIFI_PKT_TOTAL_SNT, &val);
163         total_tx = (guint64)val + tx_diff;
164
165         netconfig_vconf_get_int(VCONFKEY_NETWORK_WIFI_PKT_TOTAL_RCV, &val);
166         total_rx = (guint64)val + rx_diff;
167
168         netconfig_set_vconf_int(VCONFKEY_NETWORK_WIFI_PKT_TOTAL_SNT, (int)total_tx, FALSE);
169         netconfig_set_vconf_int(VCONFKEY_NETWORK_WIFI_PKT_TOTAL_RCV, (int)total_rx, FALSE);
170 }
171
172 void netconfig_wifi_reset_last_bytes(void)
173 {
174         netconfig_set_vconf_int(VCONFKEY_NETWORK_WIFI_PKT_LAST_SNT, 0, FALSE);
175         netconfig_set_vconf_int(VCONFKEY_NETWORK_WIFI_PKT_LAST_RCV, 0, FALSE);
176 }
177
178 static gboolean handle_get_wifi_total_tx_bytes(
179                 Network_statistics *object,
180                 GDBusMethodInvocation *context)
181 {
182         int wifi_state = 0;
183         guint64 tx = 0, rx = 0;
184         guint64 tx_bytes = 0;
185         guint64 total_bytes = 0;
186         int val = 0;
187
188         netconfig_vconf_get_int(VCONFKEY_WIFI_STATE, &wifi_state);
189
190         netconfig_vconf_get_int(VCONFKEY_NETWORK_WIFI_PKT_TOTAL_SNT, &val);
191         tx_bytes = (guint64)val;
192
193         if (wifi_state != VCONFKEY_WIFI_CONNECTED) {
194                 total_bytes = tx_bytes;
195                 network_statistics_complete_get_wifi_total_tx_bytes(object, context, total_bytes);
196                 return TRUE;
197         }
198
199         if (netconfig_wifi_get_bytes_statistics(&tx, &rx, FALSE) == TRUE)
200                 total_bytes = tx + tx_bytes;
201         else
202                 total_bytes = tx_bytes;
203
204         network_statistics_complete_get_wifi_total_tx_bytes(object, context, total_bytes);
205         return TRUE;
206 }
207
208 static gboolean handle_get_wifi_total_rx_bytes(
209                 Network_statistics *object,
210                 GDBusMethodInvocation *context)
211 {
212         int wifi_state = 0;
213         guint64 tx = 0, rx = 0;
214         guint64 rx_bytes = 0;
215         guint64 total_bytes = 0;
216         int val = 0;
217
218         netconfig_vconf_get_int(VCONFKEY_WIFI_STATE, &wifi_state);
219
220         netconfig_vconf_get_int(VCONFKEY_NETWORK_WIFI_PKT_TOTAL_RCV, &val);
221         rx_bytes = (guint64)val;
222
223         if (wifi_state != VCONFKEY_WIFI_CONNECTED) {
224                 total_bytes = rx_bytes;
225                 network_statistics_complete_get_wifi_total_rx_bytes(object, context, total_bytes);
226                 return TRUE;
227         }
228
229         if (netconfig_wifi_get_bytes_statistics(&tx, &rx, FALSE) == TRUE)
230                 total_bytes = rx + rx_bytes;
231         else
232                 total_bytes = rx_bytes;
233
234         network_statistics_complete_get_wifi_total_rx_bytes(object, context, total_bytes);
235         return TRUE;
236 }
237
238 static gboolean handle_get_wifi_last_tx_bytes(
239                 Network_statistics *object,
240                 GDBusMethodInvocation *context)
241 {
242         int wifi_state = 0;
243         guint64 tx = 0, rx = 0;
244         guint64 tx_bytes = 0;
245         guint64 last_bytes = 0;
246         int val = 0;
247
248         netconfig_vconf_get_int(VCONFKEY_WIFI_STATE, &wifi_state);
249
250         netconfig_vconf_get_int(VCONFKEY_NETWORK_WIFI_PKT_LAST_SNT, &val);
251         tx_bytes = (guint64)val;
252
253         if (wifi_state != VCONFKEY_WIFI_CONNECTED) {
254                 last_bytes = tx_bytes;
255                 network_statistics_complete_get_wifi_last_tx_bytes(object, context, last_bytes);
256                 return TRUE;
257         }
258
259         if (netconfig_wifi_get_bytes_statistics(&tx, &rx, FALSE) == TRUE)
260                 last_bytes = tx + tx_bytes;
261         else
262                 last_bytes = tx_bytes;
263
264         network_statistics_complete_get_wifi_last_tx_bytes(object, context, last_bytes);
265         return TRUE;
266 }
267
268 static gboolean handle_get_wifi_last_rx_bytes(
269                 Network_statistics *object,
270                 GDBusMethodInvocation *context)
271 {
272         int wifi_state = 0;
273         guint64 tx = 0, rx = 0;
274         guint64 rx_bytes = 0;
275         guint64 last_bytes = 0;
276         int val = 0;
277
278         netconfig_vconf_get_int(VCONFKEY_WIFI_STATE, &wifi_state);
279
280         netconfig_vconf_get_int(VCONFKEY_NETWORK_WIFI_PKT_LAST_RCV, &val);
281         rx_bytes = (guint64)val;
282
283         if (wifi_state != VCONFKEY_WIFI_CONNECTED) {
284                 last_bytes = rx_bytes;
285                 network_statistics_complete_get_wifi_last_rx_bytes(object, context, last_bytes);
286                 return TRUE;
287         }
288
289         if (netconfig_wifi_get_bytes_statistics(&tx, &rx, FALSE) == TRUE)
290                 last_bytes = rx + rx_bytes;
291         else
292                 last_bytes = rx_bytes;
293
294         network_statistics_complete_get_wifi_last_rx_bytes(object, context, last_bytes);
295         return TRUE;
296 }
297
298 static gboolean handle_reset_cellular_total_tx_bytes(
299                 Network_statistics *object,
300                 GDBusMethodInvocation *context)
301 {
302         netconfig_set_vconf_int(VCONFKEY_NETWORK_CELLULAR_PKT_TOTAL_SNT, 0, TRUE);
303         network_statistics_complete_reset_cellular_total_tx_bytes(object, context);
304         return TRUE;
305 }
306
307 static gboolean handle_reset_cellular_total_rx_bytes(
308                 Network_statistics *object,
309                 GDBusMethodInvocation *context)
310 {
311         netconfig_set_vconf_int(VCONFKEY_NETWORK_CELLULAR_PKT_TOTAL_RCV, 0, TRUE);
312         network_statistics_complete_reset_cellular_total_rx_bytes(object, context);
313         return TRUE;
314 }
315
316 static gboolean handle_reset_cellular_last_tx_bytes(
317                 Network_statistics *object,
318                 GDBusMethodInvocation *context)
319 {
320         netconfig_set_vconf_int(VCONFKEY_NETWORK_CELLULAR_PKT_LAST_SNT, 0, TRUE);
321         network_statistics_complete_reset_cellular_last_tx_bytes(object, context);
322         return TRUE;
323 }
324
325 static gboolean handle_reset_cellular_last_rx_bytes(
326                 Network_statistics *object,
327                 GDBusMethodInvocation *context)
328 {
329         netconfig_set_vconf_int(VCONFKEY_NETWORK_CELLULAR_PKT_LAST_RCV, 0, TRUE);
330         network_statistics_complete_reset_cellular_last_rx_bytes(object, context);
331         return TRUE;
332 }
333
334 static gboolean handle_reset_wifi_total_tx_bytes(
335                 Network_statistics *object,
336                 GDBusMethodInvocation *context)
337 {
338         netconfig_set_vconf_int(VCONFKEY_NETWORK_WIFI_PKT_TOTAL_SNT, 0, TRUE);
339         network_statistics_complete_reset_wifi_total_tx_bytes(object, context);
340         return TRUE;
341 }
342
343 static gboolean handle_reset_wifi_total_rx_bytes(
344                 Network_statistics *object,
345                 GDBusMethodInvocation *context)
346 {
347         netconfig_set_vconf_int(VCONFKEY_NETWORK_WIFI_PKT_TOTAL_RCV, 0, TRUE);
348         network_statistics_complete_reset_wifi_total_rx_bytes(object, context);
349         return TRUE;
350 }
351
352 static gboolean handle_reset_wifi_last_tx_bytes(
353                 Network_statistics *object,
354                 GDBusMethodInvocation *context)
355 {
356         netconfig_set_vconf_int(VCONFKEY_NETWORK_WIFI_PKT_LAST_SNT, 0, TRUE);
357         network_statistics_complete_reset_wifi_last_tx_bytes(object, context);
358         return TRUE;
359 }
360
361 static gboolean handle_reset_wifi_last_rx_bytes(
362                 Network_statistics *object,
363                 GDBusMethodInvocation *context)
364 {
365         netconfig_set_vconf_int(VCONFKEY_NETWORK_WIFI_PKT_LAST_RCV, 0, TRUE);
366         network_statistics_complete_reset_wifi_last_rx_bytes(object, context);
367         return TRUE;
368 }
369
370 static void wifi_statistics_update_state(void)
371 {
372         guint64 tx, rx;
373
374         netconfig_wifi_get_bytes_statistics(&tx, &rx, TRUE);
375 }
376
377 void statistics_object_create_and_init(void)
378 {
379         DBG("Creating statistics object");
380         GDBusInterfaceSkeleton *interface_statistics = NULL;
381         GDBusConnection *connection = NULL;
382         GDBusObjectManagerServer *server = netdbus_get_statistics_manager();
383         if (server == NULL)
384                 return;
385
386         connection = netdbus_get_connection();
387         g_dbus_object_manager_server_set_connection(server, connection);
388
389         /*Interface netconfig.network_statistics*/
390         netconfigstatistics = network_statistics_skeleton_new();
391
392         interface_statistics = G_DBUS_INTERFACE_SKELETON(netconfigstatistics);
393         g_signal_connect(netconfigstatistics, "handle-get-wifi-last-rx-bytes",
394                                 G_CALLBACK(handle_get_wifi_last_rx_bytes), NULL);
395         g_signal_connect(netconfigstatistics, "handle-get-wifi-last-tx-bytes",
396                                 G_CALLBACK(handle_get_wifi_last_tx_bytes), NULL);
397         g_signal_connect(netconfigstatistics, "handle-get-wifi-total-rx-bytes",
398                                 G_CALLBACK(handle_get_wifi_total_rx_bytes), NULL);
399         g_signal_connect(netconfigstatistics, "handle-get-wifi-total-tx-bytes",
400                                 G_CALLBACK(handle_get_wifi_total_tx_bytes), NULL);
401         g_signal_connect(netconfigstatistics, "handle-reset-cellular-last-rx-bytes",
402                                 G_CALLBACK(handle_reset_cellular_last_rx_bytes), NULL);
403         g_signal_connect(netconfigstatistics, "handle-reset-cellular-last-tx-bytes",
404                                 G_CALLBACK(handle_reset_cellular_last_tx_bytes), NULL);
405         g_signal_connect(netconfigstatistics, "handle-reset-cellular-total-rx-bytes",
406                                 G_CALLBACK(handle_reset_cellular_total_rx_bytes), NULL);
407         g_signal_connect(netconfigstatistics, "handle-reset-cellular-total-tx-bytes",
408                                 G_CALLBACK(handle_reset_cellular_total_tx_bytes), NULL);
409         g_signal_connect(netconfigstatistics, "handle-reset-wifi-last-rx-bytes",
410                                 G_CALLBACK(handle_reset_wifi_last_rx_bytes), NULL);
411         g_signal_connect(netconfigstatistics, "handle-reset-wifi-last-tx-bytes",
412                                 G_CALLBACK(handle_reset_wifi_last_tx_bytes), NULL);
413         g_signal_connect(netconfigstatistics, "handle-reset-wifi-total-rx-bytes",
414                                 G_CALLBACK(handle_reset_wifi_total_rx_bytes), NULL);
415         g_signal_connect(netconfigstatistics, "handle-reset-wifi-total-tx-bytes",
416                                 G_CALLBACK(handle_reset_wifi_total_tx_bytes), NULL);
417
418         if (!g_dbus_interface_skeleton_export(interface_statistics, connection,
419                         NETCONFIG_NETWORK_STATISTICS_PATH, NULL)) {
420                 ERR("Export with path failed");
421         }
422
423         wifi_statistics_update_state();
424
425         return;
426 }
427
428 void statistics_object_deinit(void)
429 {
430         g_object_unref(netconfigstatistics);
431 }