Fix wrong print format
[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-statistics.h"
28
29 #include "generated-code.h"
30
31 #define NETCONFIG_PROCDEV                                       "/proc/net/dev"
32
33 static Network_statistics *netconfigstatistics = NULL;
34
35 gboolean netconfig_wifi_get_bytes_statistics(guint64 *tx, guint64 *rx)
36 {
37         gboolean ret = FALSE;
38         FILE *fp;
39         gchar buf[1024];
40         gchar *p_ifname = NULL, *p_entry = NULL;
41
42         *tx = 0;
43         *rx = 0;
44
45         DBG("open /proc/net/dev file");
46         fp = fopen(NETCONFIG_PROCDEV, "r");
47         if (fp == NULL) {
48                 ERR("Failed to open %s", NETCONFIG_PROCDEV);
49                 return FALSE;
50         }
51
52         /* skip the first and second line */
53         if (fgets(buf, sizeof(buf), fp) == NULL ||
54                         fgets(buf, sizeof(buf), fp) == NULL)
55                 goto endline;
56
57         while (fgets(buf, sizeof(buf), fp)) {
58                 long long unsigned int llval;
59                 gulong lval;
60
61                 p_ifname = buf;
62                 while (*p_ifname == ' ') p_ifname++;
63                 p_entry = strchr(p_ifname, ':');
64                 if (p_entry != NULL) {
65                         *p_entry++ = '\0';
66
67                 if (g_strcmp0(p_ifname, WIFI_IFNAME) != 0)
68                         continue;
69
70                 /* read interface statistics */
71                 sscanf(p_entry,
72                                 "%llu %llu %lu %lu %lu %lu %lu %lu "
73                                 "%llu %llu %lu %lu %lu %lu %lu %lu",
74                                 (long long unsigned int *)rx, /* rx bytes */
75                                 &llval,         /* rx packet */
76                                 &lval,          /* rx errors */
77                                 &lval,          /* rx dropped */
78                                 &lval,          /* rx fifo errors */
79                                 &lval,          /* rx frame errors */
80                                 &lval,          /* rx compressed */
81                                 &lval,          /* rx multicast */
82
83                                 (long long unsigned int *)tx, /* tx bytes */
84                                 &llval,         /* tx packet */
85                                 &lval,          /* tx errors */
86                                 &lval,          /* tx dropped */
87                                 &lval,          /* tx fifo errors */
88                                 &lval,          /* collisions */
89                                 &lval,          /* tx carrier errors */
90                                 &lval           /* tx compressed */
91                                 );
92                 } else {
93                         ERR("No matched Iface name in proc file");
94                 }
95                 ret = TRUE;
96                 break;
97         }
98
99 endline:
100         fclose(fp);
101         return ret;
102 }
103
104 static gboolean handle_get_wifi_total_tx_bytes(
105                 Network_statistics *object,
106                 GDBusMethodInvocation *context)
107 {
108         guint64 tx = 0, rx = 0;
109         guint64 tx_bytes = 0;
110         guint64 total_bytes = 0;
111         int val = 0;
112
113         netconfig_vconf_get_int(VCONFKEY_NETWORK_WIFI_PKT_TOTAL_SNT, &val);
114         tx_bytes = (guint64)val;
115
116         if (netconfig_wifi_get_bytes_statistics(&tx, &rx) == TRUE)
117                 total_bytes = tx + tx_bytes;
118         else
119                 total_bytes = tx_bytes;
120
121         network_statistics_complete_get_wifi_total_tx_bytes(object, context, total_bytes);
122         return TRUE;
123 }
124
125 static gboolean handle_get_wifi_total_rx_bytes(
126                 Network_statistics *object,
127                 GDBusMethodInvocation *context)
128 {
129         guint64 tx = 0, rx = 0;
130         guint64 rx_bytes = 0;
131         guint64 total_bytes = 0;
132         int val = 0;
133
134         DBG("+");
135         netconfig_vconf_get_int(VCONFKEY_NETWORK_WIFI_PKT_TOTAL_RCV, &val);
136         rx_bytes = (guint64)val;
137
138         DBG("got rx packet size from vconf [%"G_GUINT64_FORMAT"]", rx_bytes);
139
140         if (netconfig_wifi_get_bytes_statistics(&tx, &rx) == TRUE)
141                 total_bytes = rx + rx_bytes;
142         else
143                 total_bytes = rx_bytes;
144
145         DBG("wifi total rx bytes [%"G_GUINT64_FORMAT"]", total_bytes);
146
147         network_statistics_complete_get_wifi_total_rx_bytes(object, context, total_bytes);
148         return TRUE;
149 }
150
151 static gboolean handle_get_wifi_last_tx_bytes(
152                 Network_statistics *object,
153                 GDBusMethodInvocation *context)
154 {
155         guint64 tx = 0, rx = 0;
156         guint64 tx_bytes = 0;
157         guint64 last_bytes = 0;
158         int val = 0;
159
160         netconfig_vconf_get_int(VCONFKEY_NETWORK_WIFI_PKT_LAST_SNT, &val);
161         tx_bytes = (guint64)val;
162
163         if (wifi_state_get_service_state() != NETCONFIG_WIFI_CONNECTED) {
164                 last_bytes = tx_bytes;
165                 network_statistics_complete_get_wifi_last_tx_bytes(object, context, last_bytes);
166                 return TRUE;
167         }
168
169         if (netconfig_wifi_get_bytes_statistics(&tx, &rx) == TRUE)
170                 last_bytes = tx < tx_bytes ? 0 : tx - tx_bytes;
171         else
172                 last_bytes = tx_bytes;
173
174         network_statistics_complete_get_wifi_last_tx_bytes(object, context, last_bytes);
175         return TRUE;
176 }
177
178 static gboolean handle_get_wifi_last_rx_bytes(
179                 Network_statistics *object,
180                 GDBusMethodInvocation *context)
181 {
182         guint64 tx = 0, rx = 0;
183         guint64 rx_bytes = 0;
184         guint64 last_bytes = 0;
185         int val = 0;
186
187         netconfig_vconf_get_int(VCONFKEY_NETWORK_WIFI_PKT_LAST_RCV, &val);
188         rx_bytes = (guint64)val;
189
190         if (wifi_state_get_service_state() != NETCONFIG_WIFI_CONNECTED) {
191                 last_bytes = rx_bytes;
192                 network_statistics_complete_get_wifi_last_rx_bytes(object, context, last_bytes);
193                 return TRUE;
194         }
195
196         if (netconfig_wifi_get_bytes_statistics(&tx, &rx) == TRUE)
197                 last_bytes = rx < rx_bytes ? 0 : rx - rx_bytes;
198         else
199                 last_bytes = rx_bytes;
200
201         network_statistics_complete_get_wifi_last_rx_bytes(object, context, last_bytes);
202         return TRUE;
203 }
204
205 static gboolean handle_reset_cellular_total_tx_bytes(
206                 Network_statistics *object,
207                 GDBusMethodInvocation *context)
208 {
209         netconfig_set_vconf_int(VCONFKEY_NETWORK_CELLULAR_PKT_TOTAL_SNT, 0);
210         network_statistics_complete_reset_cellular_total_tx_bytes(object, context);
211         return TRUE;
212 }
213
214 static gboolean handle_reset_cellular_total_rx_bytes(
215                 Network_statistics *object,
216                 GDBusMethodInvocation *context)
217 {
218         netconfig_set_vconf_int(VCONFKEY_NETWORK_CELLULAR_PKT_TOTAL_RCV, 0);
219         network_statistics_complete_reset_cellular_total_rx_bytes(object, context);
220         return TRUE;
221 }
222
223 static gboolean handle_reset_cellular_last_tx_bytes(
224                 Network_statistics *object,
225                 GDBusMethodInvocation *context)
226 {
227         netconfig_set_vconf_int(VCONFKEY_NETWORK_CELLULAR_PKT_LAST_SNT, 0);
228         network_statistics_complete_reset_cellular_last_tx_bytes(object, context);
229         return TRUE;
230 }
231
232 static gboolean handle_reset_cellular_last_rx_bytes(
233                 Network_statistics *object,
234                 GDBusMethodInvocation *context)
235 {
236         netconfig_set_vconf_int(VCONFKEY_NETWORK_CELLULAR_PKT_LAST_RCV, 0);
237         network_statistics_complete_reset_cellular_last_rx_bytes(object, context);
238         return TRUE;
239 }
240
241 static gboolean handle_reset_wifi_total_tx_bytes(
242                 Network_statistics *object,
243                 GDBusMethodInvocation *context)
244 {
245         guint64 tx = 0, rx = 0;
246
247         if (netconfig_wifi_get_bytes_statistics(&tx, &rx) == TRUE)
248                 netconfig_set_vconf_int(VCONFKEY_NETWORK_WIFI_PKT_TOTAL_SNT, -(int)tx);
249         else
250                 netconfig_set_vconf_int(VCONFKEY_NETWORK_WIFI_PKT_TOTAL_SNT, 0);
251
252         network_statistics_complete_reset_wifi_total_tx_bytes(object, context);
253
254         return TRUE;
255 }
256
257 static gboolean handle_reset_wifi_total_rx_bytes(
258                 Network_statistics *object,
259                 GDBusMethodInvocation *context)
260 {
261         guint64 tx = 0, rx = 0;
262
263         if (netconfig_wifi_get_bytes_statistics(&tx, &rx) == TRUE)
264                 netconfig_set_vconf_int(VCONFKEY_NETWORK_WIFI_PKT_TOTAL_RCV, -(int)rx);
265         else
266                 netconfig_set_vconf_int(VCONFKEY_NETWORK_WIFI_PKT_TOTAL_RCV, 0);
267
268         network_statistics_complete_reset_wifi_total_rx_bytes(object, context);
269         return TRUE;
270 }
271
272 static gboolean handle_reset_wifi_last_tx_bytes(
273                 Network_statistics *object,
274                 GDBusMethodInvocation *context)
275 {
276         guint64 tx = 0, rx = 0;
277
278         if (wifi_state_get_service_state() != NETCONFIG_WIFI_CONNECTED) {
279                 netconfig_set_vconf_int(VCONFKEY_NETWORK_WIFI_PKT_LAST_SNT, 0);
280                 network_statistics_complete_reset_wifi_last_tx_bytes(object, context);
281                 return TRUE;
282         }
283
284         if (netconfig_wifi_get_bytes_statistics(&tx, &rx) == TRUE)
285                 netconfig_set_vconf_int(VCONFKEY_NETWORK_WIFI_PKT_LAST_SNT, (int)tx);
286         else
287                 netconfig_set_vconf_int(VCONFKEY_NETWORK_WIFI_PKT_LAST_SNT, 0);
288
289         network_statistics_complete_reset_wifi_last_tx_bytes(object, context);
290
291         return TRUE;
292 }
293
294 static gboolean handle_reset_wifi_last_rx_bytes(
295                 Network_statistics *object,
296                 GDBusMethodInvocation *context)
297 {
298         guint64 tx = 0, rx = 0;
299
300         if (wifi_state_get_service_state() != NETCONFIG_WIFI_CONNECTED) {
301                 netconfig_set_vconf_int(VCONFKEY_NETWORK_WIFI_PKT_LAST_RCV, 0);
302                 network_statistics_complete_reset_wifi_last_rx_bytes(object, context);
303                 return TRUE;
304         }
305
306         if (netconfig_wifi_get_bytes_statistics(&tx, &rx) == TRUE)
307                 netconfig_set_vconf_int(VCONFKEY_NETWORK_WIFI_PKT_LAST_RCV, (int)rx);
308         else
309                 netconfig_set_vconf_int(VCONFKEY_NETWORK_WIFI_PKT_LAST_RCV, 0);
310
311         network_statistics_complete_reset_wifi_last_rx_bytes(object, context);
312
313         return TRUE;
314 }
315
316 void netconfig_wifi_statistics_update_powered_off(void)
317 {
318         guint64 cur_tx = 0, cur_rx = 0;
319         guint64 prev_tx = 0, prev_rx = 0;
320         guint64 total_tx = 0, total_rx = 0;
321         int val = 0;
322
323         if (netconfig_wifi_get_bytes_statistics(&cur_tx, &cur_rx) != TRUE)
324                 return;
325
326         netconfig_vconf_get_int(VCONFKEY_NETWORK_WIFI_PKT_TOTAL_SNT, &val);
327         prev_tx = (guint64)val;
328
329         netconfig_vconf_get_int(VCONFKEY_NETWORK_WIFI_PKT_TOTAL_RCV, &val);
330         prev_rx = (guint64)val;
331
332         total_tx = prev_tx + cur_tx;
333         total_rx = prev_rx + cur_rx;
334
335         netconfig_set_vconf_int(VCONFKEY_NETWORK_WIFI_PKT_TOTAL_SNT, (int)total_tx);
336         netconfig_set_vconf_int(VCONFKEY_NETWORK_WIFI_PKT_TOTAL_RCV, (int)total_rx);
337 }
338
339 static void wifi_statistics_update_state(wifi_service_state_e state, void *user_data)
340 {
341         guint64 tx = 0, rx = 0;
342         guint64 last_tx = 0, last_rx = 0;
343         int val = 0;
344         static wifi_service_state_e prev_state = NETCONFIG_WIFI_UNKNOWN;
345
346         if (prev_state == NETCONFIG_WIFI_UNKNOWN) {
347                 netconfig_set_vconf_int(VCONFKEY_NETWORK_WIFI_PKT_LAST_SNT, 0);
348                 netconfig_set_vconf_int(VCONFKEY_NETWORK_WIFI_PKT_LAST_RCV, 0);
349
350                 prev_state = NETCONFIG_WIFI_IDLE;
351                 return;
352         }
353
354         if (netconfig_wifi_get_bytes_statistics(&tx, &rx) != TRUE)
355                 return;
356
357         if (state == NETCONFIG_WIFI_CONNECTED) {
358                 last_tx = tx;
359                 last_rx = rx;
360         } else {
361                 if (prev_state != NETCONFIG_WIFI_CONNECTED)
362                         return;
363
364                 netconfig_vconf_get_int(VCONFKEY_NETWORK_WIFI_PKT_LAST_SNT, &val);
365                 last_tx = (guint64)val;
366
367                 netconfig_vconf_get_int(VCONFKEY_NETWORK_WIFI_PKT_LAST_RCV, &val);
368                 last_rx = (guint64)val;
369
370                 last_tx = tx < last_tx ? 0 : tx - last_tx;
371                 last_rx = rx < last_rx ? 0 : rx - last_rx;
372         }
373
374         netconfig_set_vconf_int(VCONFKEY_NETWORK_WIFI_PKT_LAST_SNT, (int)last_tx);
375         netconfig_set_vconf_int(VCONFKEY_NETWORK_WIFI_PKT_LAST_RCV, (int)last_rx);
376
377         prev_state = state;
378 }
379
380 static wifi_state_notifier state_notifier = {
381                 .wifi_state_changed = wifi_statistics_update_state,
382                 .user_data = NULL,
383 };
384
385 void statistics_object_create_and_init(void)
386 {
387         DBG("Creating statistics object");
388         GDBusInterfaceSkeleton *interface_statistics = NULL;
389         GDBusConnection *connection = NULL;
390         GDBusObjectManagerServer *server = netdbus_get_statistics_manager();
391         if (server == NULL)
392                 return;
393
394         connection = netdbus_get_connection();
395         g_dbus_object_manager_server_set_connection(server, connection);
396
397         /*Interface netconfig.network_statistics*/
398         netconfigstatistics = network_statistics_skeleton_new();
399
400         interface_statistics = G_DBUS_INTERFACE_SKELETON(netconfigstatistics);
401         g_signal_connect(netconfigstatistics, "handle-get-wifi-last-rx-bytes",
402                                 G_CALLBACK(handle_get_wifi_last_rx_bytes), NULL);
403         g_signal_connect(netconfigstatistics, "handle-get-wifi-last-tx-bytes",
404                                 G_CALLBACK(handle_get_wifi_last_tx_bytes), NULL);
405         g_signal_connect(netconfigstatistics, "handle-get-wifi-total-rx-bytes",
406                                 G_CALLBACK(handle_get_wifi_total_rx_bytes), NULL);
407         g_signal_connect(netconfigstatistics, "handle-get-wifi-total-tx-bytes",
408                                 G_CALLBACK(handle_get_wifi_total_tx_bytes), NULL);
409         g_signal_connect(netconfigstatistics, "handle-reset-cellular-last-rx-bytes",
410                                 G_CALLBACK(handle_reset_cellular_last_rx_bytes), NULL);
411         g_signal_connect(netconfigstatistics, "handle-reset-cellular-last-tx-bytes",
412                                 G_CALLBACK(handle_reset_cellular_last_tx_bytes), NULL);
413         g_signal_connect(netconfigstatistics, "handle-reset-cellular-total-rx-bytes",
414                                 G_CALLBACK(handle_reset_cellular_total_rx_bytes), NULL);
415         g_signal_connect(netconfigstatistics, "handle-reset-cellular-total-tx-bytes",
416                                 G_CALLBACK(handle_reset_cellular_total_tx_bytes), NULL);
417         g_signal_connect(netconfigstatistics, "handle-reset-wifi-last-rx-bytes",
418                                 G_CALLBACK(handle_reset_wifi_last_rx_bytes), NULL);
419         g_signal_connect(netconfigstatistics, "handle-reset-wifi-last-tx-bytes",
420                                 G_CALLBACK(handle_reset_wifi_last_tx_bytes), NULL);
421         g_signal_connect(netconfigstatistics, "handle-reset-wifi-total-rx-bytes",
422                                 G_CALLBACK(handle_reset_wifi_total_rx_bytes), NULL);
423         g_signal_connect(netconfigstatistics, "handle-reset-wifi-total-tx-bytes",
424                                 G_CALLBACK(handle_reset_wifi_total_tx_bytes), NULL);
425
426         if (!g_dbus_interface_skeleton_export(interface_statistics, connection,
427                         NETCONFIG_NETWORK_STATISTICS_PATH, NULL)) {
428                 ERR("Export with path failed");
429         }
430
431         wifi_statistics_update_state(NETCONFIG_WIFI_IDLE, NULL);
432         wifi_state_notifier_register(&state_notifier);
433
434         return;
435 }
436
437 void statistics_object_deinit(void)
438 {
439         g_object_unref(netconfigstatistics);
440 }