Modified to get current time to match stc
[platform/core/connectivity/net-config.git] / plugin / battery / battery.c
1 /*
2  * Network Configuration Module
3  *
4  * Copyright (c) 2017 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 "plugin.h"
21 #include "util.h"
22
23 #ifdef USE_NETCONFIG_LOG
24 #include "log.h"
25 #else
26 #include <dlog.h>
27
28 #define NETCONFIG_TAG           "NETCONFIG"
29 #define __LOG(level, format, arg...) \
30         do { \
31                 SLOG(level, NETCONFIG_TAG, format, ## arg); \
32         } while (0)
33
34 #define DBG(format, arg...)     __LOG(LOG_DEBUG, format, ## arg)
35 #define ERR(format, arg...)     __LOG(LOG_ERROR, format, ## arg)
36 #endif
37
38 #define BATTERY_MODE_END   0
39 #define BATTERY_MODE_GET   1
40
41 typedef struct {
42         time_t time;
43 } battery_scan_data_s;
44
45 typedef struct {
46         time_t time;
47         int rssi;
48 } battery_rssi_data_s;
49
50 static battery_scan_data_s g_wifi_scan_data = { 0, };
51
52 static battery_rssi_data_s g_dn_rssi_data = { 0, };
53 static battery_rssi_data_s g_wifi_rssi_data = { 0, };
54
55 static battery_dn_data_s *g_dn_data = NULL;
56 static battery_wifi_data_s *g_wifi_data = NULL;
57
58 static GSList *g_dn_list = NULL;
59 static GSList *g_wifi_list = NULL;
60
61 static void __battery_free_app_data(void *data)
62 {
63         battery_app_data_s *app_data = (battery_app_data_s *)data;
64
65         g_free(app_data->app_id);
66         g_free(app_data);
67 }
68
69 static void __battery_free_dn_data(void *data)
70 {
71         battery_dn_data_s *dn_data = (battery_dn_data_s *)data;
72
73         g_slist_free_full(dn_data->atm_list, __battery_free_app_data);
74         g_free(dn_data);
75 }
76
77 static void __battery_flush_dn_list(void)
78 {
79         g_slist_free_full(g_dn_list, __battery_free_dn_data);
80         g_dn_list = NULL;
81 }
82
83 static void __battery_free_wifi_data(void *data)
84 {
85         battery_wifi_data_s *wifi_data = (battery_wifi_data_s *)data;
86
87         g_slist_free_full(wifi_data->atm_list, __battery_free_app_data);
88         g_free(wifi_data);
89 }
90
91 static void __battery_flush_wifi_list(void)
92 {
93         g_slist_free_full(g_wifi_list, __battery_free_wifi_data);
94         g_wifi_list = NULL;
95 }
96
97 static void __battery_print_dn_list(void)
98 {
99         GSList *list = NULL;
100
101         for (list = g_dn_list; list != NULL; list = list->next) {
102                 battery_dn_data_s *dn_data = (battery_dn_data_s *)list->data;
103                 DBG("[Battery DN] rssi[%d/%d/%d/%d/%d/%d/%d]",
104                         dn_data->time_level_0, dn_data->time_level_1, dn_data->time_level_2,
105                         dn_data->time_level_3, dn_data->time_level_4, dn_data->time_level_5,
106                         dn_data->time_level_6);
107         }
108 }
109
110 static void __battery_print_wifi_list(void)
111 {
112         GSList* list = NULL;
113
114         for (list = g_wifi_list; list != NULL; list = list->next) {
115                 battery_wifi_data_s *wifi_data = (battery_wifi_data_s *)list->data;
116                 DBG("[Battery Wi-Fi] start[%ld] end[%ld] scan[%d] rssi[%d/%d/%d/%d/%d]",
117                         wifi_data->start_time, wifi_data->end_time, wifi_data->scan_time,
118                         wifi_data->time_level_0, wifi_data->time_level_1, wifi_data->time_level_2,
119                         wifi_data->time_level_3, wifi_data->time_level_4);
120         }
121 }
122
123 static void __battery_get_dn_list(void *data, battery_dn_data_s *dn_data)
124 {
125         GVariantBuilder *builder = (GVariantBuilder *)data;
126         GVariantBuilder sub_builder;
127
128         g_variant_builder_init(&sub_builder, G_VARIANT_TYPE("a{sv}"));
129
130         g_variant_builder_add(&sub_builder, "{sv}", BATTERY_DN_TIME_LEVEL_0,
131                 g_variant_new_uint32(dn_data->time_level_0));
132         g_variant_builder_add(&sub_builder, "{sv}", BATTERY_DN_TIME_LEVEL_1,
133                 g_variant_new_uint32(dn_data->time_level_1));
134         g_variant_builder_add(&sub_builder, "{sv}", BATTERY_DN_TIME_LEVEL_2,
135                 g_variant_new_uint32(dn_data->time_level_2));
136         g_variant_builder_add(&sub_builder, "{sv}", BATTERY_DN_TIME_LEVEL_3,
137                 g_variant_new_uint32(dn_data->time_level_3));
138         g_variant_builder_add(&sub_builder, "{sv}", BATTERY_DN_TIME_LEVEL_4,
139                 g_variant_new_uint32(dn_data->time_level_4));
140         g_variant_builder_add(&sub_builder, "{sv}", BATTERY_DN_TIME_LEVEL_5,
141                 g_variant_new_uint32(dn_data->time_level_5));
142         g_variant_builder_add(&sub_builder, "{sv}", BATTERY_DN_TIME_LEVEL_6,
143                 g_variant_new_uint32(dn_data->time_level_6));
144
145         DBG("[Battery DN] rssi[%d/%d/%d/%d/%d/%d/%d]",
146                         dn_data->time_level_0, dn_data->time_level_1, dn_data->time_level_2,
147                         dn_data->time_level_3, dn_data->time_level_4, dn_data->time_level_5,
148                         dn_data->time_level_6);
149
150         if (dn_data->atm_list != NULL) {
151                 GSList *list = NULL;
152                 GVariantBuilder atm_builder;
153
154                 g_variant_builder_init(&atm_builder, G_VARIANT_TYPE("aa{sv}"));
155
156                 for (list = dn_data->atm_list; list != NULL; list = list->next) {
157                         battery_app_data_s *app_data = (battery_app_data_s *)list->data;
158
159                         g_variant_builder_open(&atm_builder, G_VARIANT_TYPE("a{sv}"));
160
161                         g_variant_builder_add(&atm_builder, "{sv}", BATTERY_ATM_APP_ID,
162                                 g_variant_new_string(app_data->app_id));
163                         g_variant_builder_add(&atm_builder, "{sv}", BATTERY_ATM_RX,
164                                 g_variant_new_uint32(app_data->rx));
165                         g_variant_builder_add(&atm_builder, "{sv}", BATTERY_ATM_TX,
166                                 g_variant_new_uint32(app_data->tx));
167
168                         g_variant_builder_close(&atm_builder);
169
170                         DBG("[Battery DN] app_id[%s] rx[%d] tx[%d]", app_data->app_id, app_data->rx, app_data->tx);
171                 }
172
173                 g_variant_builder_add(&sub_builder, "{sv}", BATTERY_ATM_LIST,
174                                                 g_variant_new_variant(g_variant_builder_end(&atm_builder)));
175         }
176
177         g_variant_builder_add_value(builder, g_variant_builder_end(&sub_builder));
178 }
179
180 static void __battery_get_wifi_list(void *data, battery_wifi_data_s *wifi_data)
181 {
182         GVariantBuilder *builder = (GVariantBuilder *)data;
183         GVariantBuilder sub_builder;
184
185         g_variant_builder_init(&sub_builder, G_VARIANT_TYPE("a{sv}"));
186
187         g_variant_builder_add(&sub_builder, "{sv}", BATTERY_WIFI_TIME_LEVEL_0,
188                 g_variant_new_uint32(wifi_data->time_level_0));
189         g_variant_builder_add(&sub_builder, "{sv}", BATTERY_WIFI_TIME_LEVEL_1,
190                 g_variant_new_uint32(wifi_data->time_level_1));
191         g_variant_builder_add(&sub_builder, "{sv}", BATTERY_WIFI_TIME_LEVEL_2,
192                 g_variant_new_uint32(wifi_data->time_level_2));
193         g_variant_builder_add(&sub_builder, "{sv}", BATTERY_WIFI_TIME_LEVEL_3,
194                 g_variant_new_uint32(wifi_data->time_level_3));
195         g_variant_builder_add(&sub_builder, "{sv}", BATTERY_WIFI_TIME_LEVEL_4,
196                 g_variant_new_uint32(wifi_data->time_level_4));
197         g_variant_builder_add(&sub_builder, "{sv}", BATTERY_WIFI_START_TIME,
198                 g_variant_new_uint32(wifi_data->start_time));
199         g_variant_builder_add(&sub_builder, "{sv}", BATTERY_WIFI_END_TIME,
200                 g_variant_new_uint32(wifi_data->end_time));
201         g_variant_builder_add(&sub_builder, "{sv}", BATTERY_WIFI_SCAN_TIME,
202                 g_variant_new_uint32(wifi_data->scan_time));
203
204         DBG("[Battery Wi-Fi] start[%ld] end[%ld] scan[%d] rssi[%d/%d/%d/%d/%d]",
205                         wifi_data->start_time, wifi_data->end_time, wifi_data->scan_time,
206                         wifi_data->time_level_0, wifi_data->time_level_1, wifi_data->time_level_2,
207                         wifi_data->time_level_3, wifi_data->time_level_4);
208
209
210         if (wifi_data->atm_list != NULL) {
211                 GSList *list = NULL;
212                 GVariantBuilder atm_builder;
213
214                 g_variant_builder_init(&atm_builder, G_VARIANT_TYPE("aa{sv}"));
215
216                 for (list = wifi_data->atm_list; list != NULL; list = list->next) {
217                         battery_app_data_s *app_data = (battery_app_data_s *)list->data;
218
219                         g_variant_builder_open(&atm_builder, G_VARIANT_TYPE("a{sv}"));
220
221                         g_variant_builder_add(&atm_builder, "{sv}", BATTERY_ATM_APP_ID,
222                                 g_variant_new_string(app_data->app_id));
223                         g_variant_builder_add(&atm_builder, "{sv}", BATTERY_ATM_RX,
224                                 g_variant_new_uint32(app_data->rx));
225                         g_variant_builder_add(&atm_builder, "{sv}", BATTERY_ATM_TX,
226                                 g_variant_new_uint32(app_data->tx));
227
228                         g_variant_builder_close(&atm_builder);
229
230                         DBG("[Battery Wi-Fi] app_id[%s] rx[%d] tx[%d]", app_data->app_id, app_data->rx, app_data->tx);
231                 }
232
233                 g_variant_builder_add(&sub_builder, "{sv}", BATTERY_ATM_LIST,
234                                                 g_variant_new_variant(g_variant_builder_end(&atm_builder)));
235         }
236
237         g_variant_builder_add_value(builder, g_variant_builder_end(&sub_builder));
238 }
239
240 void battery_update_dn_rssi(int rssi)
241 {
242         time_t curr_time = time(NULL);
243
244         if (g_dn_data == NULL)
245                 return;
246
247         DBG("[Battery DN] rssi(%ld) [%d]", curr_time, rssi);
248
249         if (g_dn_rssi_data.time != 0) {
250                 uint diff_time = curr_time - g_dn_rssi_data.time;
251                 diff_time = (diff_time > 0) ? diff_time : 1;
252                 switch (g_dn_rssi_data.rssi) {
253                 case 0:
254                         g_dn_data->time_level_0 += diff_time;
255                         DBG("[Battery DN] level 0 time [%d/%d]", diff_time, g_dn_data->time_level_0);
256                         break;
257                 case 1:
258                         g_dn_data->time_level_1 += diff_time;
259                         DBG("[Battery DN] level 1 time [%d/%d]", diff_time, g_dn_data->time_level_1);
260                         break;
261                 case 2:
262                         g_dn_data->time_level_2 += diff_time;
263                         DBG("[Battery DN] level 2 time [%d/%d]", diff_time, g_dn_data->time_level_2);
264                         break;
265                 case 3:
266                         g_dn_data->time_level_3 += diff_time;
267                         DBG("[Battery DN] level 3 time [%d/%d]", diff_time, g_dn_data->time_level_3);
268                         break;
269                 case 4:
270                         g_dn_data->time_level_4 += diff_time;
271                         DBG("[Battery DN] level 4 time [%d/%d]", diff_time, g_dn_data->time_level_4);
272                         break;
273                 case 5:
274                         g_dn_data->time_level_5 += diff_time;
275                         DBG("[Battery DN] level 5 time [%d/%d]", diff_time, g_dn_data->time_level_5);
276                         break;
277                 case 6:
278                         g_dn_data->time_level_6 += diff_time;
279                         DBG("[Battery DN] level 6 time [%d/%d]", diff_time, g_dn_data->time_level_6);
280                         break;
281                 default:
282                         break;
283                 }
284         }
285
286         if (rssi >= 0) {
287                 g_dn_rssi_data.time = curr_time;
288                 g_dn_rssi_data.rssi = rssi;
289         }
290 }
291
292 void battery_start_dn_data(void)
293 {
294         battery_dn_data_s *dn_data = NULL;
295         time_t curr_time = time(NULL);
296
297         if (g_dn_data != NULL)
298                 return;
299
300         __battery_print_dn_list();
301
302         dn_data = (battery_dn_data_s *)g_try_malloc0(sizeof(battery_dn_data_s));
303         if (dn_data == NULL)
304                 return;
305
306         memset(dn_data, 0, sizeof(battery_dn_data_s));
307         dn_data->start_time = curr_time;
308
309         g_dn_data = dn_data;
310         g_dn_list = g_slist_append(g_dn_list, g_dn_data);
311
312         if (g_dn_rssi_data.time != 0)
313                 g_dn_rssi_data.time = curr_time;
314
315         DBG("[Battery DN] start(%ld)", g_dn_data->start_time);
316 }
317
318 void battery_end_dn_data(int mode, stc_get_stats_cb get_stats_cb)
319 {
320         time_t curr_time = time(NULL);
321
322         if (g_dn_data == NULL)
323                 return;
324
325         battery_update_dn_rssi(-1);
326
327         if (mode == BATTERY_MODE_END) {
328                 g_dn_rssi_data.time = 0;
329                 g_dn_rssi_data.rssi = 0;
330         }
331
332         g_dn_data->end_time = curr_time;
333
334         get_stats_cb(g_dn_data->start_time, g_dn_data->end_time, &(g_dn_data->atm_list));
335
336         g_dn_data = NULL;
337
338         DBG("[Battery DN] end");
339 }
340
341 void battery_update_wifi_scan(int state)
342 {
343         time_t curr_time = time(NULL);
344
345         if (g_wifi_data == NULL)
346                 return;
347
348         switch (state) {
349         case 0: /* scan done */
350                 DBG("[Battery Wi-Fi] scan(%ld) [done]", curr_time);
351                 if (g_wifi_scan_data.time != 0) {
352                         uint diff_time = curr_time - g_wifi_scan_data.time;
353                         diff_time = (diff_time > 0) ? diff_time : 1;
354                         g_wifi_data->scan_time += diff_time;
355                         DBG("[Battery Wi-Fi] scan time [%d/%d]", diff_time, g_wifi_data->scan_time);
356                 }
357                 break;
358         case 1: /* scan started */
359                 g_wifi_scan_data.time = curr_time;
360                 DBG("[Battery Wi-Fi] scan(%ld) [started]", curr_time);
361                 break;
362         default:
363                 break;
364         }
365 }
366
367 void battery_update_wifi_rssi(int rssi)
368 {
369         time_t curr_time = time(NULL);
370
371         if (g_wifi_data == NULL)
372                 return;
373
374         DBG("[Battery Wi-Fi] rssi(%ld) [%d]", curr_time, rssi);
375
376         if (g_wifi_rssi_data.time != 0) {
377                 uint diff_time = curr_time - g_wifi_rssi_data.time;
378                 diff_time = (diff_time > 0) ? diff_time : 1;
379                 switch (g_wifi_rssi_data.rssi) {
380                 case 0:
381                         g_wifi_data->time_level_0 += diff_time;
382                         DBG("[Battery Wi-Fi] level 0 time [%d/%d]", diff_time, g_wifi_data->time_level_0);
383                         break;
384                 case 1:
385                         g_wifi_data->time_level_1 += diff_time;
386                         DBG("[Battery Wi-Fi] level 1 time [%d/%d]", diff_time, g_wifi_data->time_level_1);
387                         break;
388                 case 2:
389                         g_wifi_data->time_level_2 += diff_time;
390                         DBG("[Battery Wi-Fi] level 2 time [%d/%d]", diff_time, g_wifi_data->time_level_2);
391                         break;
392                 case 3:
393                         g_wifi_data->time_level_3 += diff_time;
394                         DBG("[Battery Wi-Fi] level 3 time [%d/%d]", diff_time, g_wifi_data->time_level_3);
395                         break;
396                 case 4:
397                         g_wifi_data->time_level_4 += diff_time;
398                         DBG("[Battery Wi-Fi] level 4 time [%d/%d]", diff_time, g_wifi_data->time_level_4);
399                         break;
400                 default:
401                         break;
402                 }
403         }
404
405         if (rssi >= 0) {
406                 g_wifi_rssi_data.time = curr_time;
407                 g_wifi_rssi_data.rssi = rssi;
408         }
409 }
410
411 void battery_start_wifi_data(void)
412 {
413         battery_wifi_data_s *wifi_data = NULL;
414         time_t curr_time = time(NULL);
415
416         if (g_wifi_data != NULL)
417                 return;
418
419         __battery_print_wifi_list();
420
421         wifi_data = (battery_wifi_data_s *)g_try_malloc0(sizeof(battery_wifi_data_s));
422         if (wifi_data == NULL)
423                 return;
424
425         memset(wifi_data, 0, sizeof(battery_wifi_data_s));
426         wifi_data->start_time = curr_time;
427
428         g_wifi_data = wifi_data;
429         g_wifi_list = g_slist_append(g_wifi_list, g_wifi_data);
430
431         if (g_wifi_rssi_data.time)
432                 g_wifi_rssi_data.time = curr_time;
433
434         DBG("[Battery Wi-Fi] start(%ld)", g_wifi_data->start_time);
435 }
436
437 void battery_end_wifi_data(int mode, stc_get_stats_cb get_stats_cb)
438 {
439         time_t curr_time = time(NULL);
440
441         if (g_wifi_data == NULL)
442                 return;
443
444         battery_update_wifi_rssi(-1);
445
446         if (mode == BATTERY_MODE_END) {
447                 g_wifi_rssi_data.time = 0;
448                 g_wifi_rssi_data.rssi = 0;
449         }
450
451         g_wifi_scan_data.time = 0;
452
453         g_wifi_data->end_time = curr_time;
454
455         get_stats_cb(g_wifi_data->start_time, g_wifi_data->end_time, &(g_wifi_data->atm_list));
456
457         g_wifi_data = NULL;
458
459         DBG("[Battery Wi-Fi] end(%ld)", curr_time);
460 }
461
462 void battery_get_dn_list(void *data, stc_get_stats_cb get_stats_cb)
463 {
464         GSList *dn_list = NULL;
465         int cont = FALSE;
466
467         if (g_dn_data != NULL)
468                 cont = TRUE;
469
470         battery_end_dn_data(BATTERY_MODE_GET, get_stats_cb);
471
472         DBG("===============================================================");
473
474         for (dn_list = g_dn_list; dn_list != NULL; dn_list = dn_list->next) {
475                 battery_dn_data_s *dn_data = (battery_dn_data_s *)dn_list->data;
476                 __battery_get_dn_list(data, dn_data);
477                 DBG("===============================================================");
478         }
479
480         __battery_flush_dn_list();
481
482         if (cont)
483                 battery_start_dn_data();
484 }
485
486 void battery_get_wifi_list(void *data, stc_get_stats_cb get_stats_cb)
487 {
488         GSList *list = NULL;
489         int cont = FALSE;
490
491         if (g_wifi_data != NULL)
492                 cont = TRUE;
493
494         battery_end_wifi_data(BATTERY_MODE_GET, get_stats_cb);
495
496         DBG("===============================================================");
497
498         for (list = g_wifi_list; list != NULL; list = list->next) {
499                 battery_wifi_data_s *wifi_data = (battery_wifi_data_s *)list->data;
500                 __battery_get_wifi_list(data, wifi_data);
501                 DBG("===============================================================");
502         }
503
504         __battery_flush_wifi_list();
505
506         if (cont)
507                 battery_start_wifi_data();
508 }
509
510 extern struct netconfig_battery_plugin_t netconfig_battery_plugin
511                 __attribute__ ((visibility("default")));
512 struct netconfig_battery_plugin_t netconfig_battery_plugin = {
513         battery_start_dn_data,
514         battery_end_dn_data,
515         battery_update_dn_rssi,
516         battery_start_wifi_data,
517         battery_end_wifi_data,
518         battery_update_wifi_scan,
519         battery_update_wifi_rssi,
520         battery_get_dn_list,
521         battery_get_wifi_list
522 };