Dump the start/end time of usage collection time
[platform/core/system/batterymonitor.git] / src / bm_power_engine.c
1 /*
2  * Copyright (c) 2019 Samsung Electronics Co., Ltd. All rights reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License")
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 #include <sys/time.h>
19
20 #include <device/battery.h>
21 #include <device/callback.h>
22 #include <runtime_info.h>
23
24 #include "bm_power_engine.h"
25 #include "bm_dbg.h"
26 #include "bm_common.h"
27 #include "bm_config_parser.h"
28 #include "bm_plugin_manager.h"
29 #include "bm_server_db.h"
30 #include "bm_private.h"
31 #include "bd_private.h"
32 #include "bm_util.h"
33 #include "bd_history_item.h"
34
35 bm_feature_data_h bm_data_handle = NULL;
36 GHashTable *gl_hash = NULL;
37 static struct bm_req_feature_data_handle_flag_s *bm_req_flag_h = NULL;
38 const double cmah = 3600;
39 int battery_capacity = 500;
40 int gtimeo_id[2];
41 static int data_collection_period = 600000;
42
43 static struct timeval last_plugin_request_time;
44 static struct timeval cur_plugin_request_time;
45
46 void bm_update_plugin_request_time(void)
47 {
48         ENTER;
49
50         if (!memcpy(&last_plugin_request_time, &cur_plugin_request_time, sizeof(struct timeval))) {
51                 _ERR("memcpy failed");
52                 return;
53         }
54
55         if (gettimeofday(&cur_plugin_request_time, NULL) != 0) {
56                 _ERR("gettimeofday failed : %m");
57                 return;
58         }
59
60         EXIT;
61         return;
62 }
63
64 int bm_engine_get_mah_usage_by_app_id_for_resource_id_ci(const gchar* app_id, gint resource_id, gint64 start_time, gint64 end_time, double *battery_usage)
65 {
66         ENTER;
67         BM_CHECK_INPUT_PARAM(app_id);
68         BM_RETURN_VAL((resource_id < BM_PLUGIN_ID_MAX), {},
69                         BATTERY_MONITOR_ERROR_INVALID_PARAMETER, "invalid resource-id param");
70         _DBG("usage requested - app-id[%s], resource_id[%d], start_time [%ld] end_time[%ld]",
71                         app_id, resource_id, (long int)start_time, (long int)end_time);
72
73         int error = BATTERY_MONITOR_ERROR_NONE;
74         appid_usage_s *app_usage = bm_server_query_app_usage_by_appid_ci(app_id, start_time, end_time, &error);
75         if (!app_usage) {
76                 _ERR("battery usage data for app_id(%s) is not available", app_id);
77                 return BATTERY_MONITOR_ERROR_INTERNAL;
78         }
79         if (error != BATTERY_MONITOR_ERROR_NONE) {
80                 _ERR("error reported, error = %d", error);
81                 return BATTERY_MONITOR_ERROR_INTERNAL;
82         }
83         if (app_usage->AppId == NULL) {
84                 _ERR("Battery Usage for AppId not found");
85                 bm_appid_usage_free(app_usage);
86                 return BATTERY_MONITOR_ERROR_RECORD_NOT_FOUND;
87         }
88
89         if (resource_id == BM_PLUGIN_ID_BLE)
90                 *battery_usage = bm_calc_individual_mah_consumption(app_usage->rId_ble, cmah);
91         else if (resource_id == BM_PLUGIN_ID_WIFI)
92                 *battery_usage = bm_calc_individual_mah_consumption(app_usage->rId_wifi, cmah);
93         else if (resource_id == BM_PLUGIN_ID_CPU)
94                 *battery_usage = bm_calc_individual_mah_consumption(app_usage->rId_cpu, cmah);
95         else if (resource_id == BM_PLUGIN_ID_DISPLAY)
96                 *battery_usage = bm_calc_individual_mah_consumption(app_usage->rId_display, cmah);
97         else if (resource_id == BM_PLUGIN_ID_DEVICE_NETWORK)
98                 *battery_usage = bm_calc_individual_mah_consumption(app_usage->rId_device_network, cmah);
99 #ifdef DISABLE_FEATURE_DATA_FROM_GPS_HRM_PLUGIN
100         else if (resource_id == BM_PLUGIN_ID_GPS_SENSOR)
101                 *battery_usage = bm_calc_individual_mah_consumption(app_usage->rId_gps, cmah);
102         else if (resource_id == BM_PLUGIN_ID_HRM_SENSOR)
103                 *battery_usage = bm_calc_individual_mah_consumption(app_usage->rId_hrm, cmah);
104         else
105                 *battery_usage = -1;
106 #endif /* DISABLE_FEATURE_DATA_FROM_GPS_HRM_PLUGIN */
107
108         bm_appid_usage_free(app_usage);
109
110         EXIT;
111         return BATTERY_MONITOR_ERROR_NONE;
112 }
113
114 int bm_engine_get_total_mah_usage_by_app_id_ci(const gchar* app_id, gint64 start_time, gint64 end_time, double *battery_usage)
115 {
116         ENTER;
117
118         BM_CHECK_INPUT_PARAM(app_id);
119
120         _DBG("usage requested - app-id[%s], start_time [%ld] end_time[%ld]",
121                         app_id, (long int)start_time, (long int)end_time);
122         int error = BATTERY_MONITOR_ERROR_NONE;
123         appid_usage_s *app_usage = bm_server_query_app_usage_by_appid_ci(app_id, start_time, end_time, &error);
124         if (!app_usage) {
125                 _ERR("battery usage data for app_id(%s) is not available", app_id);
126                 return BATTERY_MONITOR_ERROR_INTERNAL;
127         }
128         if (error != BATTERY_MONITOR_ERROR_NONE) {
129                 _ERR("error reported, error = %d", error);
130                 return BATTERY_MONITOR_ERROR_INTERNAL;
131         }
132         if (app_usage->AppId == NULL) {
133                 _ERR("Battery Usage for AppId not found");
134                 bm_appid_usage_free(app_usage);
135                 return BATTERY_MONITOR_ERROR_RECORD_NOT_FOUND;
136         }
137         int total_consumption = (app_usage->rId_ble + app_usage->rId_wifi + app_usage->rId_cpu + \
138                         app_usage->rId_display + app_usage->rId_device_network);
139 #ifdef DISABLE_FEATURE_DATA_FROM_GPS_HRM_PLUGIN
140         total_consumption += (app_usage->rId_gps + app_usage->rId_hrm);
141 #endif /* DISABLE_FEATURE_DATA_FROM_GPS_HRM_PLUGIN */
142         *battery_usage = bm_calc_individual_mah_consumption(total_consumption, cmah);
143         _INFO("total battery consumption is [%lf] for app-id[%s]", *battery_usage, app_id);
144
145         bm_appid_usage_free(app_usage);
146         EXIT;
147         return BATTERY_MONITOR_ERROR_NONE;
148 }
149
150 int bm_engine_get_total_mah_usage_by_resource_id_ci(gint resource_id, gint64 start_time, gint64 end_time, double *battery_usage)
151 {
152         ENTER;
153
154         BM_RETURN_VAL((resource_id < BM_PLUGIN_ID_MAX), {},
155                         BATTERY_MONITOR_ERROR_INVALID_PARAMETER, "invalid resource-id");
156         _DBG("usage requested - resource_id[%d], start_time [%ld] end_time[%ld]",
157                         resource_id, (long int)start_time, (long int)end_time);
158
159         int error = BATTERY_MONITOR_ERROR_NONE;
160         const char *resource_id_str = NULL;
161         resource_id_str = bm_get_resource_id_string(resource_id);
162         if (g_strcmp0(resource_id_str, "UNKNOWN RESOURCE-ID") == 0) {
163                 _ERR("invalid resource-id");
164                 return BATTERY_MONITOR_ERROR_INTERNAL;
165         }
166         _INFO("resource string - [%s]", resource_id_str);
167         resourceid_usage_s *resource_usage = bm_server_query_resource_usage_resourceid_ci(resource_id_str, start_time, end_time, &error);
168         if (!resource_usage) {
169                 _ERR("battery usage data for resource-id(%s) is not available", resource_id_str);
170                 return BATTERY_MONITOR_ERROR_INTERNAL;
171         }
172         if (error != BATTERY_MONITOR_ERROR_NONE) {
173                 _ERR("error reported, error = %d", error);
174                 return BATTERY_MONITOR_ERROR_INTERNAL;
175         }
176         if (resource_usage->ResourceId == NULL) {
177                  _ERR("Battery Usage for ResourceId not found");
178                  bm_resourceid_usage_free(resource_usage);
179                  return BATTERY_MONITOR_ERROR_RECORD_NOT_FOUND;
180         }
181
182         *battery_usage = bm_calc_individual_mah_consumption(resource_usage->usage, cmah);
183         bm_resourceid_usage_free(resource_usage);
184
185         EXIT;
186         return BATTERY_MONITOR_ERROR_NONE;
187 }
188
189 int bm_engine_get_all_resource_usage_handle_ci(const gchar* app_id, gint64 start_time, gint64 end_time, bm_total_consumption_h battery_data)
190 {
191         ENTER;
192         BM_CHECK_INPUT_PARAM(app_id);
193         BM_CHECK_INPUT_PARAM(battery_data);
194         _DBG("usage requested - app-id[%s], start_time[%ld] end_time[%ld]", \
195                         app_id, (long int)start_time, (long int)end_time);
196         int error = BATTERY_MONITOR_ERROR_NONE;
197         appid_usage_s *app_usage = bm_server_query_app_usage_by_appid_ci(app_id, start_time, end_time, &error);
198         if (!app_usage) {
199                 _ERR("battery usage data for app_id(%s) is not available", app_id);
200                 return BATTERY_MONITOR_ERROR_INTERNAL;
201         }
202         if (error != BATTERY_MONITOR_ERROR_NONE) {
203                 _ERR("error reported, error = %d", error);
204                 return BATTERY_MONITOR_ERROR_INTERNAL;
205         }
206         if (app_usage->AppId == NULL) {
207                 _ERR("Battery Usage for AppId not found");
208                 bm_appid_usage_free(app_usage);
209                 return BATTERY_MONITOR_ERROR_RECORD_NOT_FOUND;
210         }
211         battery_data->ble_val = app_usage->rId_ble; battery_data->wifi_val = app_usage->rId_wifi;
212         battery_data->cpu_val = app_usage->rId_cpu; battery_data->dp_val = app_usage->rId_display;
213         battery_data->dn_val = app_usage->rId_device_network;
214 #ifdef DISABLE_FEATURE_DATA_FROM_GPS_HRM_PLUGIN
215         battery_data->gps_val = app_usage->rId_gps; battery_data->hrm_val = app_usage->rId_hrm;
216         battery_data->bat_val = app_usage->rId_battery;
217 #endif /* DISABLE_FEATURE_DATA_FROM_GPS_HRM_PLUGIN */
218
219         bm_appid_usage_free(app_usage);
220
221         EXIT;
222         return BATTERY_MONITOR_ERROR_NONE;
223 }
224
225 void bm_engine_set_req_flag_handle(bm_plugin_id_e req_plugin_id, bool value)
226 {
227         ENTER;
228
229         if (!bm_req_flag_h) {
230                 _ERR("invalid flag handle");
231                 return;
232         }
233
234         switch (req_plugin_id) {
235         case BM_PLUGIN_ID_BLE:
236                 bm_req_flag_h->req_ble_data = value;
237                 break;
238         case BM_PLUGIN_ID_WIFI:
239                 bm_req_flag_h->req_wifi_data = value;
240                 break;
241         case BM_PLUGIN_ID_CPU:
242                 bm_req_flag_h->req_cpu_data = value;
243                 break;
244         case BM_PLUGIN_ID_DISPLAY:
245                 bm_req_flag_h->req_dp_data = value;
246                 break;
247         case BM_PLUGIN_ID_DEVICE_NETWORK:
248                 bm_req_flag_h->req_dn_data = value;
249                 break;
250 #ifdef DISABLE_FEATURE_DATA_FROM_GPS_HRM_PLUGIN
251         case BM_PLUGIN_ID_GPS_SENSOR:
252                 bm_req_flag_h->req_gps_data = value;
253                 break;
254         case BM_PLUGIN_ID_HRM_SENSOR:
255                 bm_req_flag_h->req_hrm_data = value;
256                 break;
257 #endif /* DISABLE_FEATURE_DATA_FROM_GPS_HRM_PLUGIN */
258         default:
259                 _DBG("Invalid plugin ID");
260                 break;
261         }
262
263         EXIT;
264         return;
265 }
266
267 void bm_set_req_flag_handles(bool value)
268 {
269         ENTER;
270
271         if (!bm_req_flag_h) {
272                 _ERR("invalid flag handle");
273                 return;
274         }
275
276         bm_req_flag_h->req_ble_data = value;
277         bm_req_flag_h->req_wifi_data = value;
278         bm_req_flag_h->req_cpu_data = value;
279         bm_req_flag_h->req_dp_data = value;
280         bm_req_flag_h->req_dn_data = value;
281 #ifdef DISABLE_FEATURE_DATA_FROM_GPS_HRM_PLUGIN
282         bm_req_flag_h->req_gps_data = value;
283         bm_req_flag_h->req_hrm_data = value;
284 #endif /* DISABLE_FEATURE_DATA_FROM_GPS_HRM_PLUGIN */
285
286         _INFO("request flags set-[%s]", (value == true) ? "TRUE" : "FALSE");
287
288         EXIT;
289         return;
290 }
291
292 static int bm_appid_session_usage_map(char *app_id, int app_usage, bm_plugin_id_e resource_id)
293 {
294         ENTER;
295
296         BM_CHECK_INPUT_PARAM(app_id);
297
298         void *prv_data = NULL;
299         void *prv_app_id = NULL;
300
301         int ret_val = BATTERY_MONITOR_ERROR_NONE;
302         _DBG("app_id [%s] app_usage is [%d]", app_id, app_usage);
303
304         if (g_hash_table_lookup_extended(gl_hash, app_id, &prv_app_id, &prv_data) == true) {
305                 appid_usage_s *temp = (appid_usage_s *)prv_data;
306                 if (resource_id == BM_PLUGIN_ID_BLE)
307                         temp->rId_ble += app_usage;
308                 else if (resource_id == BM_PLUGIN_ID_WIFI)
309                         temp->rId_wifi += app_usage;
310                 else if (resource_id == BM_PLUGIN_ID_CPU)
311                         temp->rId_cpu += app_usage;
312                 else if (resource_id == BM_PLUGIN_ID_DISPLAY)
313                         temp->rId_display += app_usage;
314                 else if (resource_id == BM_PLUGIN_ID_DEVICE_NETWORK)
315                         temp->rId_device_network += app_usage;
316 #ifdef DISABLE_FEATURE_DATA_FROM_GPS_HRM_PLUGIN
317                 else if (resource_id == BM_PLUGIN_ID_GPS_SENSOR)
318                         temp->rId_gps += app_usage;
319                 else if (resource_id == BM_PLUGIN_ID_HRM_SENSOR)
320                         temp->rId_hrm += app_usage;
321 #endif /* DISABLE_FEATURE_DATA_FROM_GPS_HRM_PLUGIN */
322
323                 _DBG("update - app_usage for app_id(%s), for resource(%d), by usage(%d)", app_id, resource_id, app_usage);
324                 //_DBG("session usage bt %d, wifi %d, cpu %d, dsp %d, dn %d", temp->rId_ble, temp->rId_wifi, temp->rId_cpu,
325                 //temp->rId_display, temp->rId_device_network);
326         } else {
327                 appid_usage_s *temp = (appid_usage_s *)calloc(1, sizeof(appid_usage_s));
328                 if (temp == NULL) {
329                         _ERR("memory allocation failed");
330                         return BATTERY_MONITOR_ERROR_OUT_OF_MEMORY;
331                 }
332
333                 if (resource_id == BM_PLUGIN_ID_BLE)
334                         temp->rId_ble = app_usage;
335                 else if (resource_id == BM_PLUGIN_ID_WIFI)
336                         temp->rId_wifi = app_usage;
337                 else if (resource_id == BM_PLUGIN_ID_CPU)
338                         temp->rId_cpu = app_usage;
339                 else if (resource_id == BM_PLUGIN_ID_DISPLAY)
340                         temp->rId_display = app_usage;
341                 else if (resource_id == BM_PLUGIN_ID_DEVICE_NETWORK)
342                         temp->rId_device_network = app_usage;
343 #ifdef DISABLE_FEATURE_DATA_FROM_GPS_HRM_PLUGIN
344                 else if (resource_id == BM_PLUGIN_ID_GPS_SENSOR)
345                         temp->rId_gps = app_usage;
346                 else if (resource_id == BM_PLUGIN_ID_HRM_SENSOR)
347                         temp->rId_hrm = app_usage;
348 #endif /* DISABLE_FEATURE_DATA_FROM_GPS_HRM_PLUGIN */
349
350                 _DBG("insert - app_usage app_id(%s), for resource(%d), by usage(%d)", app_id, resource_id, app_usage);
351
352                 _INFO("inserted - %d", g_hash_table_insert(gl_hash, g_strdup(app_id), temp));
353         }
354
355         EXIT;
356         return ret_val;
357 }
358
359 static int bm_insert_appid_session_usage_to_db()
360 {
361         ENTER;
362
363         GHashTableIter iter;
364         gpointer key, value;
365         appid_usage_s *app_usage = NULL;
366
367         int ret_val = BATTERY_MONITOR_ERROR_NONE;
368
369         long int ret_time = bm_get_log_time(data_collection_period);
370
371         g_hash_table_iter_init(&iter, gl_hash);
372
373         while (g_hash_table_iter_next(&iter, &key, &value)) {
374                 app_usage = (appid_usage_s *)value;
375                 app_usage->AppId = (char *)key;
376                 app_usage->log_time = ret_time;
377
378                 _DBG("Calculated Power for Appid(%s) for resources bt(%d), wifi(%d), cpu(%d), \
379                         display(%d), dn(%d)", app_usage->AppId, app_usage->rId_ble,
380                         app_usage->rId_wifi, app_usage->rId_cpu, app_usage->rId_display,
381                                         app_usage->rId_device_network);
382
383                 ret_val = bm_server_appid_insert_to_db(app_usage->AppId);
384                 if (ret_val != BATTERY_MONITOR_ERROR_NONE)
385                         _ERR("Insert of Appid failed ");
386                 else
387                         _DBG("Insert successful");
388
389                 ret_val = bm_server_app_usage_insert_to_db(app_usage);
390                 if (ret_val != BATTERY_MONITOR_ERROR_NONE)
391                         _ERR("Insert of App Usage failed ");
392                 else
393                         _DBG("Insert successful");
394         }
395
396         EXIT;
397         return ret_val;
398 }
399
400 /* TODO: Add Normalization of values based on sP_Power_xxx & Time unit */
401 int bm_ble_calc_power_and_commit(bm_bluetooth_st *handle, bool mode)
402 {
403         ENTER;
404
405         BM_CHECK_INPUT_PARAM(handle);
406
407         GSList *bt_data_iterator = NULL;
408         GSList *bt_atm_iterator = NULL;
409         void *prv_data = NULL;
410         void *prv_app_id = NULL;
411         int ret_val = BATTERY_MONITOR_ERROR_NONE;
412
413         /* creating hash-map with (key, value) = (app-id, data) */
414         GHashTable *hash = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, NULL);
415
416         long int edTime = 0, stTime = 0;
417         long int sesTime = 0, conTime = 0, RX_app = 0, TX_app = 0;
418         long int RX_system = 0, TX_system = 0, tx_time = 0, rx_time = 0;
419         long int scTime = 0;
420         double onTime = 0;
421         /* iterating over list for data accumulation */
422         for (bt_data_iterator = handle->bt_data_list; bt_data_iterator; bt_data_iterator = bt_data_iterator->next) {
423                 bm_bluetooth_st *datalistnode = (bm_bluetooth_st *)(bt_data_iterator->data);
424                 edTime = datalistnode->stopTime; stTime = datalistnode->startTime;
425 //              scTime += datalistnode->scanTime;
426                 conTime += datalistnode->connectedTime;
427                 rx_time += datalistnode->rxTime; tx_time += datalistnode->txTime;
428                 sesTime += (edTime-stTime);
429                 bt_atm_iterator = datalistnode->atm_list;
430                 for ( ; bt_atm_iterator; bt_atm_iterator = bt_atm_iterator->next) {
431                         app_time_map_st2 *bt_atm_node = NULL;
432                         bt_atm_node = bt_atm_iterator->data;
433                         if (!bt_atm_node) {
434                                 _DBG("no data available");
435                                 continue;
436                         }
437                         _DBG("bt data available");
438
439                         /* Get the system usage */
440                         if (g_strcmp0(bt_atm_node->app_id, BM_APPID_SYSTEM) == 0) {
441                                 _DBG("ignore - app_id(%s), time(%d), rx(%d), tx(%d)", bt_atm_node->app_id,
442                                                 bt_atm_node->time, bt_atm_node->rx, bt_atm_node->tx);
443
444                                 RX_system += bt_atm_node->rx;
445                                 TX_system += bt_atm_node->tx;
446                                 continue;
447                         }
448
449                         RX_app += bt_atm_node->rx;
450                         TX_app += bt_atm_node->tx;
451                         onTime += bt_atm_node->time;
452                         prv_data = NULL;
453                         prv_app_id = NULL;
454                         if (g_hash_table_lookup_extended(hash, bt_atm_node->app_id, &prv_app_id, &prv_data) == true) {
455                                 _DBG("previous app_id = %s", (char *)prv_app_id);
456                                 app_time_map_st2 *temp = (app_time_map_st2 *)prv_data;
457                                 bt_atm_node->time += temp->time;
458                                 bt_atm_node->rx += temp->rx;
459                                 bt_atm_node->tx += temp->tx;
460                                 _DBG("update - app_id(%s), time(%d), rx(%d), tx(%d)", bt_atm_node->app_id,
461                                                 bt_atm_node->time, bt_atm_node->rx, bt_atm_node->tx);
462                                 _INFO("updated - %d", g_hash_table_replace(hash, bt_atm_node->app_id, bt_atm_node));
463                         } else {
464                                 _DBG("insert - app_id(%s), time(%d), rx(%d), tx(%d)", bt_atm_node->app_id,
465                                                 bt_atm_node->time, bt_atm_node->rx, bt_atm_node->tx);
466                                 _INFO("inserted - %d", g_hash_table_insert(hash, bt_atm_node->app_id, bt_atm_node));
467                         }
468                 }
469         }
470         // startTime and stopTime use seconds. So, we don't have to convert sesTime
471         conTime /= 1000; rx_time /= 1000; tx_time /= 1000;
472
473         /* Read standard Rated Values from Device Spec File/Power Profile File */
474         double sP_power_bt_idle = 0, sP_power_bt_scan = 0, sP_power_bt_conn = 0, sP_power_bt_tx = 0, sP_power_bt_rx = 0;
475
476         ret_val = bm_get_blutooth_power_params(&sP_power_bt_idle, &sP_power_bt_scan, &sP_power_bt_conn, &sP_power_bt_rx, &sP_power_bt_tx);
477         if (ret_val != BATTERY_MONITOR_ERROR_NONE)
478                 _ERR("failed to get bt power params");
479
480         _DBG("received bt power params - idle[%lf], scan[%lf], connected[%lf], rx[%lf], tx[%lf]",
481                         sP_power_bt_idle, sP_power_bt_scan, sP_power_bt_conn, sP_power_bt_tx, sP_power_bt_rx);
482         /* BT power consumption Level - 1 at the Resource Level */
483         long int P_power_bt = 0, P_power_data = 0, P_power_conn = 0;
484         /* Remove transmit time from connected time */
485         long int rconTime = conTime - (rx_time + tx_time);
486         P_power_conn = ((sP_power_bt_idle) * (sesTime - conTime)) + ((sP_power_bt_conn) * (rconTime));
487         /* Amount based usage calculation */
488 //      P_power_data = ((sP_power_bt_tx) * TX_app) + ((sP_power_bt_rx) * RX_app);
489
490         /* Use rx and tx time to calculate the usage */
491         P_power_data = ((sP_power_bt_tx) * tx_time + (sP_power_bt_rx) * rx_time);
492         P_power_bt = P_power_conn + P_power_data;
493
494         _DBG("Calculated Power for Bluetooth P_power_bt(%ld),  P_power_conn (%ld), P_power_data(%ld)", P_power_bt, P_power_conn, P_power_data);
495         /* BT power consumption Level - 2 at the Application Level */
496         GHashTableIter iter1;
497         gpointer key, value;
498         g_hash_table_iter_init(&iter1, hash);
499
500         long int rx_tx_time = tx_time + rx_time;
501         long int left_rx_tx_time = rx_tx_time;
502         double apptime = 0, csc_t = 0;
503         //Normalize
504         if (onTime != 0 && onTime > rx_tx_time) {
505                 _DBG("Normalize the scan app scan time");
506                 csc_t = (double)rx_tx_time/onTime;
507                 while (g_hash_table_iter_next(&iter1, &key, &value)) {
508                         app_time_map_st2 *temp = (app_time_map_st2 *)value;
509                         apptime = temp->time;
510                         if (temp->time > 0) {
511                                 temp->time = (apptime * csc_t);
512                                 left_rx_tx_time -= temp->time;
513                         }
514                 }
515         } else
516                 left_rx_tx_time -= onTime;
517
518         long int P_power_app_bt = 0, P_power_app_data = 0, P_power_app_conn = 0;
519         char *appid = NULL;
520         long int apprx = 0, apptx = 0;
521         long int ret_time = bm_get_log_time(data_collection_period);
522         long int total_app_pw = 0, base_res_pw = 0;
523
524         /* Coefficient to divide the rx and tx time wrt rx and tx bytes */
525         double crtx_t = 0;
526         if ((left_rx_tx_time > 0) && (RX_app != 0 || TX_app != 0))
527                 crtx_t = (double)left_rx_tx_time/(TX_app + RX_app + RX_system + TX_system);
528
529         appid_usage_s app_usage;
530
531         GHashTableIter iter;
532         g_hash_table_iter_init(&iter, hash);
533         while (g_hash_table_iter_next(&iter, &key, &value)) {
534                 P_power_app_bt = 0, P_power_app_data = 0, P_power_app_conn = 0;
535                 apprx = 0, apptx = 0, apptime = 0;
536                 app_time_map_st2 *temp = (app_time_map_st2 *)value;
537                 appid = temp->app_id;
538                 apprx = temp->rx; apptx = temp->tx;
539                 apptime = temp->time;
540 //              P_power_app_data = (sP_power_bt_tx * (crx_t * apptx)) + (sP_power_bt_rx * (ctx_t * apprx));
541 //              if (onTime != 0)
542 //                      P_power_app_conn = (P_power_conn * apptime)/onTime; //check for 0 denominator & same units
543 //              P_power_app_bt = P_power_app_data + P_power_app_conn;
544                 int app_transmit = apprx + apptx;
545                 P_power_app_bt = sP_power_bt_rx * ((crtx_t * app_transmit) + apptime);
546                 app_usage.AppId = appid;
547                 app_usage.rId_ble = P_power_app_bt;
548                 app_usage.log_time = ret_time;
549                 total_app_pw += P_power_app_bt;
550                 /* Call Insert Function */
551                 _DBG("Calculated Power for Appid(%s) -  P_power_app_bt(%ld), P_power_app_conn(%ld), P_power_app_data(%ld)",
552                                         appid, P_power_app_bt, P_power_app_conn, P_power_app_data);
553                 if (mode) {
554                         ret_val = bm_server_appid_insert_to_db(app_usage.AppId);
555                         if (ret_val != BATTERY_MONITOR_ERROR_NONE)
556                                 _ERR("Insert of BT appid failed ");
557                         ret_val = bm_server_app_usage_insert_to_db(&app_usage);
558                 } else/* Call Global Hash */
559                         ret_val = bm_appid_session_usage_map(app_usage.AppId, app_usage.rId_ble, BM_PLUGIN_ID_BLE);
560                 if (ret_val != BATTERY_MONITOR_ERROR_NONE)
561                         _ERR("Insert of BT App failed ");
562         }
563
564         /* commit to database the output after power calculation */
565         resourceid_usage_s res_usage;
566
567         res_usage.ResourceId = BM_RID_BLE;
568         res_usage.log_time = ret_time;
569         res_usage.usage = P_power_bt;
570         ret_val = bm_server_resource_usage_insert_to_db(&res_usage);
571         if (ret_val != BATTERY_MONITOR_ERROR_NONE)
572                 _ERR("Insert of BT resource failed ");
573
574         if (P_power_bt > total_app_pw) {
575                 base_res_pw = (P_power_bt - total_app_pw);
576                 res_usage.usage = base_res_pw;
577                 ret_val = bm_server_resource_base_usage_insert_to_db(&res_usage);
578                 if (ret_val != BATTERY_MONITOR_ERROR_NONE)
579                         _ERR("Insert of BT base resource failed ");
580         }
581
582         bd_gl_ble_stat_s *gble_st = (bd_gl_ble_stat_s *)calloc(1, sizeof(bd_gl_ble_stat_s));
583         if (gble_st == NULL) {
584                 _ERR("memory allocation failed");
585                 return BATTERY_MONITOR_ERROR_OUT_OF_MEMORY;
586         }
587         gble_st->time_s = ret_time; gble_st->ble_idle_time = (sesTime - (scTime + conTime));
588         gble_st->ble_rx_time = rx_time;
589         gble_st->ble_tx_time = tx_time;
590         gble_st->ble_pwi_val = P_power_bt;
591
592         ret_val = bm_server_battery_dump_insert_to_db(gble_st, 0);
593         if (ret_val != BATTERY_MONITOR_ERROR_NONE)
594                 _ERR("Insert of GBLE failed ");
595         BM_FREE(gble_st);
596         bd_gl_bst_stat_s *gbst_st = (bd_gl_bst_stat_s *)calloc(1, sizeof(bd_gl_bst_stat_s));
597         if (gbst_st == NULL) {
598                 _ERR("memory allocation failed");
599                 return BATTERY_MONITOR_ERROR_OUT_OF_MEMORY;
600         }
601         gbst_st->time_s = ret_time; gbst_st->off_time = data_collection_period / 1000;
602         gbst_st->off_time -= sesTime; gbst_st->low_time = 0/*(sesTime - (scTime + conTime))*/;
603         gbst_st->med_time = 0/*scTime*/; gbst_st->high_time = 0/*conTime*/;
604         ret_val = bm_server_battery_dump_insert_to_db(gbst_st, 6);
605         if (ret_val != BATTERY_MONITOR_ERROR_NONE)
606                 _ERR("Insert of GBLE failed ");
607         BM_FREE(gbst_st);
608         /* Free the hash map */
609         g_hash_table_destroy(hash);
610
611         /* Dump resource usage */
612         _DBG("BLE usage : %ld bytes", RX_system + TX_system + RX_app + TX_app);
613         if (RX_system > 0 || TX_system > 0 || RX_app > 0 || TX_app > 0) {
614                 history_item_s hi;
615                 bd_print_history_item_reset(&hi);
616
617                 hi.time_current = (long long)last_plugin_request_time.tv_sec;
618
619                 hi.cmd_s = CM_USAGE;
620                 hi.usage_type = USAGE_BLUETOOTH;
621                 hi.usage = (RX_system + TX_system + RX_app + TX_app) / ((double)data_collection_period / 60000);        // bytes / minute
622
623                 bd_store_history_item(&hi);
624         }
625
626         EXIT;
627         return ret_val;
628 }
629
630 int bm_wifi_calc_power_and_commit(bm_wifi_st *handle, bool mode)
631 {
632         ENTER;
633
634         BM_CHECK_INPUT_PARAM(handle);
635
636         GSList *wifi_data_iterator = NULL;
637         GSList *wifi_atm_iterator = NULL;
638         void *prv_data = NULL;
639         void *prv_app_id = NULL;
640         int ret_val = BATTERY_MONITOR_ERROR_NONE;
641
642         /* creating hash-map with (key, value) = (app-id, data) */
643         GHashTable *hash = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, NULL);
644
645         long int edTime = 0, stTime = 0;
646         long int sesTime = 0, scTime = 0, tl_total = 0;
647         long int tl0 = 0, tl1 = 0, tl2 = 0, tl3 = 0, tl4 = 0;
648         double onTime = 0;
649         long int RX = 0, TX = 0, rx_time = 0, tx_time = 0;
650         /* iterating over list for data accumulation */
651         for (wifi_data_iterator = handle->wifi_data_list; wifi_data_iterator; wifi_data_iterator = wifi_data_iterator->next) {
652                 bm_wifi_st *datalistnode = (bm_wifi_st *)(wifi_data_iterator->data);
653                 edTime = datalistnode->endTime;
654                 stTime = datalistnode->startTime;
655                 sesTime += (edTime - stTime);
656                 scTime += datalistnode->scanTime;
657                 tl0 += datalistnode->time_level_0; tl1 += datalistnode->time_level_1;
658                 tl2 += datalistnode->time_level_2; tl3 += datalistnode->time_level_3;
659                 tl4 += datalistnode->time_level_4;
660                 rx_time += datalistnode->rxTime; tx_time += datalistnode->txTime;
661                 wifi_atm_iterator = datalistnode->atm_list;
662                 for ( ; wifi_atm_iterator; wifi_atm_iterator = wifi_atm_iterator->next) {
663                         app_time_map_st2 *wifi_atm_node = NULL;
664                         wifi_atm_node = wifi_atm_iterator->data;
665                         if (!wifi_atm_node) {
666                                 _DBG("no data available");
667                                 continue;
668                         }
669                         _DBG("wifi data available");
670                         RX += wifi_atm_node->rx;
671                         TX += wifi_atm_node->tx;
672                         onTime += wifi_atm_node->time;
673                         prv_app_id = NULL;
674                         prv_data = NULL;
675                         if (g_hash_table_lookup_extended(hash, wifi_atm_node->app_id, &prv_app_id, &prv_data) == true) {
676                                 _DBG("previous app_id = %s", (char *)prv_app_id);
677                                 app_time_map_st2 *temp = (app_time_map_st2 *)prv_data;
678                                 wifi_atm_node->time += temp->time;
679                                 wifi_atm_node->rx += temp->rx;
680                                 wifi_atm_node->tx += temp->tx;
681                                 _DBG("update - app_id(%s), time(%d), rx(%d), tx(%d)", wifi_atm_node->app_id,
682                                                 wifi_atm_node->time, wifi_atm_node->rx, wifi_atm_node->tx);
683                                 _INFO("updated - %d", g_hash_table_replace(hash, wifi_atm_node->app_id, wifi_atm_node));
684                         } else {
685                                 _DBG("insert - app_id(%s), time(%d), rx(%d), tx(%d)", wifi_atm_node->app_id,
686                                                 wifi_atm_node->time, wifi_atm_node->rx, wifi_atm_node->tx);
687                                 _INFO("inserted - %d", g_hash_table_insert(hash, wifi_atm_node->app_id, wifi_atm_node));
688                         }
689                 }
690         }
691
692         /* Read standard Rated Values from Device Spec File/Power Profile File */
693         double sP_power_wf_idle = 0, sP_power_wf_scan = 0, sP_power_wf_tl0 = 0, sP_power_wf_tl1 = 0, sP_power_wf_tl2 = 0;
694         double sP_power_wf_tl3 = 0, sP_power_wf_tl4 = 0, sP_power_wf_tx = 0, sP_power_wf_rx = 0;
695
696         ret_val = bm_get_wifi_power_params(&sP_power_wf_tl0, &sP_power_wf_tl1, &sP_power_wf_tl2, &sP_power_wf_tl3,
697                                 &sP_power_wf_tl4, &sP_power_wf_scan, &sP_power_wf_idle, &sP_power_wf_rx, &sP_power_wf_tx);
698         if (ret_val != BATTERY_MONITOR_ERROR_NONE)
699                 _ERR("failed to get wifi power params");
700
701         _DBG("received wifi power params - rssi_0[%lf], rssi_1[%lf], rssi_2[%lf], rssi_3[%lf], rssi_4[%lf], scan[%lf], \
702                         idle[%lf], rx[%lf], tx[%lf]", sP_power_wf_tl0, sP_power_wf_tl1, sP_power_wf_tl2, sP_power_wf_tl3,
703                         sP_power_wf_tl4, sP_power_wf_scan, sP_power_wf_idle, sP_power_wf_rx, sP_power_wf_tx);
704
705         tl0 /= 1000; tl1 /= 1000; tl2 /= 1000; tl3 /= 1000;  tl4 /= 1000;
706         onTime /= 1000;
707         rx_time /= 1000; tx_time /= 1000;
708         tl_total = tl0 + tl1 + tl2 + tl3 + tl4;
709         /* Wifi power consumption Level - 1 at the Resource Level */
710         long int P_power_wifi = 0, P_power_data = 0, P_power_conn = 0;
711         P_power_conn = ((sP_power_wf_tl0 * tl0) + (sP_power_wf_tl1 * tl1) +
712                         (sP_power_wf_tl2 * tl2) + (sP_power_wf_tl3 * tl3) +
713                         (sP_power_wf_tl4 * tl4) + (sP_power_wf_scan * scTime) +
714                         (sP_power_wf_idle * (sesTime - (tl_total + scTime))));
715         /* Amount based usage calculation */
716 //      P_power_data = ((sP_power_wf_tx) * TX) + ((sP_power_wf_rx) * RX);
717
718         /* Use rx and tx time to calculate the usage */
719         P_power_data = ((sP_power_wf_tx * tx_time) + (sP_power_wf_rx * rx_time));
720         P_power_wifi = P_power_conn + P_power_data;
721
722         _DBG("Calculated Power for Wifi P_power_wifi(%ld),  P_power_conn (%ld), P_power_data(%ld)", P_power_wifi, P_power_conn, P_power_data);
723         /* Wifi power consumption Level - 2 at the Application Level */
724         GHashTableIter iter;
725         gpointer key, value;
726         g_hash_table_iter_init(&iter, hash);
727
728         long int P_power_app_wifi = 0, P_power_app_data = 0, P_power_app_conn = 0;
729         char *appid = NULL;
730         long int apprx = 0, apptx = 0;
731         double apptime = 0, crx_t = 0, ctx_t = 0;
732         long int rx_t = 0, tx_t = 0;
733         long int ret_time = bm_get_log_time(data_collection_period);
734         long int total_app_pw = 0, base_res_pw = 0;
735
736         /* Coefficient to divide the rx and tx time wrt rx and tx bytes */
737         if (RX != 0)
738                 crx_t = (double)rx_time/RX;
739         if (TX != 0)
740                 ctx_t = (double)tx_time/TX;
741
742         appid_usage_s app_usage;
743
744         while (g_hash_table_iter_next(&iter, &key, &value)) {
745                 P_power_app_wifi = 0; P_power_app_data = 0; P_power_app_conn = 0;
746                 apprx = 0, apptx = 0, apptime = 0;
747                 app_time_map_st2 *temp = (app_time_map_st2 *)value;
748                 appid = temp->app_id;
749                 apprx = temp->rx; rx_t += apprx;
750                 apptx = temp->tx; tx_t += apptx;
751                 apptime = temp->time;
752                 apptime /= 1000;
753                 P_power_app_data = (sP_power_wf_tx * (ctx_t * apptx)) + (sP_power_wf_rx * (crx_t * apprx));
754
755                 if (onTime != 0)
756                         P_power_app_conn = (P_power_conn * apptime)/onTime; //check for 0 denominator & same units
757                 P_power_app_wifi = P_power_app_data + P_power_app_conn;
758
759                 app_usage.AppId = appid;
760                 app_usage.rId_wifi = P_power_app_wifi;
761                 app_usage.log_time = ret_time;
762                 total_app_pw += P_power_app_wifi;
763                 /* Call Insert Function */
764                 _DBG("Calculated Power for Appid(%s) -  P_power_app_wifi(%ld), P_power_app_conn(%ld), P_power_app_data(%ld)",
765                                         appid, P_power_app_wifi, P_power_app_conn, P_power_app_data);
766
767                 if (mode) {
768                         ret_val = bm_server_appid_insert_to_db(app_usage.AppId);
769                         if (ret_val != BATTERY_MONITOR_ERROR_NONE)
770                                 _ERR("Insert of WiFi appid failed ");
771                         ret_val = bm_server_app_usage_insert_to_db(&app_usage);
772                 } else/* Call Global Hash */
773                         ret_val = bm_appid_session_usage_map(app_usage.AppId, app_usage.rId_wifi, BM_PLUGIN_ID_WIFI);
774                 if (ret_val != BATTERY_MONITOR_ERROR_NONE)
775                         _ERR("Insert of Wifi App failed ");
776         }
777
778         /* commit to database the output after power calculation */
779         resourceid_usage_s res_usage;
780
781         res_usage.ResourceId = BM_RID_WIFI;
782         res_usage.log_time = ret_time;
783         res_usage.usage = P_power_wifi;
784         ret_val = bm_server_resource_usage_insert_to_db(&res_usage);
785         if (ret_val != BATTERY_MONITOR_ERROR_NONE)
786                 _ERR("Insert of Wifi resource failed ");
787
788         if (P_power_wifi > total_app_pw) {
789                 base_res_pw = (P_power_wifi - total_app_pw);
790                 res_usage.usage = base_res_pw;
791                 ret_val = bm_server_resource_base_usage_insert_to_db(&res_usage);
792                 if (ret_val != BATTERY_MONITOR_ERROR_NONE)
793                         _ERR("Insert of Wifi base resource failed ");
794         }
795
796         bd_gl_wifi_stat_s *gwfl_st = (bd_gl_wifi_stat_s *)calloc(1, sizeof(bd_gl_wifi_stat_s));
797         if (gwfl_st == NULL) {
798                 _ERR("memory allocation failed");
799                 return BATTERY_MONITOR_ERROR_OUT_OF_MEMORY;
800         }
801         gwfl_st->time_s = ret_time; gwfl_st->wifi_on_time = sesTime;
802         gwfl_st->wifi_conn_time = tl_total; gwfl_st->wifi_idle_time = (sesTime - (tl_total + scTime));
803         gwfl_st->wifi_rx_time = rx_time;
804         gwfl_st->wifi_tx_time = tx_time;
805         ret_val = bm_server_battery_dump_insert_to_db(gwfl_st, 1);
806         if (ret_val != BATTERY_MONITOR_ERROR_NONE)
807                 _ERR("Insert of GWFL failed ");
808         else
809                 _DBG("Insert successful");
810         BM_FREE(gwfl_st);
811         bd_gl_wst_stat_s *gwst_st = (bd_gl_wst_stat_s *)calloc(1, sizeof(bd_gl_wst_stat_s));
812         if (gwst_st == NULL) {
813                 _ERR("memory allocation failed");
814                 return BATTERY_MONITOR_ERROR_OUT_OF_MEMORY;
815         }
816         gwst_st->time_s = ret_time; gwst_st->wscan_time = scTime;
817         gwst_st->wnone_time = tl0; gwst_st->wpoor_time = tl1; gwst_st->wmed_time = tl2;
818         gwst_st->wgood_time = tl3; gwst_st->wgrt_time = tl4;
819         ret_val = bm_server_battery_dump_insert_to_db(gwst_st, 5);
820         if (ret_val != BATTERY_MONITOR_ERROR_NONE)
821                 _ERR("Insert of GWFL failed ");
822         else
823                 _DBG("Insert successful");
824         BM_FREE(gwst_st);
825
826         /* Free the Hash Map */
827         g_hash_table_destroy(hash);
828
829         /* Dump resource usage */
830         _DBG("Wi-Fi usage : %ld bytes", RX + TX);
831         if (RX > 0 || TX > 0) {
832                 history_item_s hi;
833                 bd_print_history_item_reset(&hi);
834
835                 hi.time_current = (long long)last_plugin_request_time.tv_sec;
836
837                 hi.cmd_s = CM_USAGE;
838                 hi.usage_type = USAGE_WIFI;
839                 hi.usage = (RX + TX) / ((double)data_collection_period / 60000);        // bytes / minute
840
841                 bd_store_history_item(&hi);
842         }
843
844         EXIT;
845         return ret_val;
846 }
847
848 int bm_cpu_calc_power_and_commit(bm_cpu_st *handle, bool mode)
849 {
850         ENTER;
851
852         BM_CHECK_INPUT_PARAM(handle);
853
854         GSList *cpu_data_iterator = NULL;
855         GSList *cpu_atm_iterator = NULL;
856         void *prv_data = NULL;
857         void *prv_app_id = NULL;
858         int ret_val = BATTERY_MONITOR_ERROR_NONE;
859
860         /* creating hash-map with (key, value) = (app-id, data) */
861         GHashTable *hash = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, NULL);
862
863         long int uTime = 0, sTime = 0;
864         double onTime = 0;
865         /* iterating over list for data accumulation */
866         for (cpu_data_iterator = handle->cpu_data_list; cpu_data_iterator; cpu_data_iterator = cpu_data_iterator->next) {
867                 bm_cpu_st *datalistnode = (bm_cpu_st *)(cpu_data_iterator->data);
868                 uTime += datalistnode->utime;
869                 sTime += datalistnode->stime;
870                 cpu_atm_iterator = datalistnode->atm_list;
871                 for ( ; cpu_atm_iterator; cpu_atm_iterator = cpu_atm_iterator->next) {
872                         app_time_map_st1 *cpu_atm_node = (app_time_map_st1 *)cpu_atm_iterator->data;
873                         if (!cpu_atm_node) {
874                                 _DBG("no data available");
875                                 continue;
876                         }
877                         _DBG("cpu data available");
878                         onTime += cpu_atm_node->time;
879                         prv_app_id = NULL;
880                         prv_data = NULL;
881                         if (g_hash_table_lookup_extended(hash, cpu_atm_node->app_id, &prv_app_id, &prv_data) == true) {
882                                 _DBG("previous app_id = %s", (char *)prv_app_id);
883                                 app_time_map_st1 *cpu_atm_prv_node = (app_time_map_st1 *)prv_data;
884                                 cpu_atm_node->time += cpu_atm_prv_node->time;
885                                 _DBG("update - app_id(%s), time(%d)", cpu_atm_node->app_id, cpu_atm_node->time);
886                                 _INFO("updated - %d", g_hash_table_replace(hash, cpu_atm_node->app_id, cpu_atm_node));
887                         } else {
888                                 _DBG("insert - app_id(%s), time(%d)", cpu_atm_node->app_id, cpu_atm_node->time);
889                                 _INFO("inserted - %d", g_hash_table_insert(hash, cpu_atm_node->app_id, cpu_atm_node));
890                         }
891                 }
892         }
893         /* Read standard Rated Values from Device Spec File/Power Profile File */
894         double sP_power_cpu_user = 0, sP_power_cpu_system = 0;
895
896         ret_val = bm_get_cpu_power_params(&sP_power_cpu_user, &sP_power_cpu_system);
897         if (ret_val != BATTERY_MONITOR_ERROR_NONE)
898                 _ERR("failed to get cpu power params");
899
900         _DBG("received cpu power params - user[%lf]\n, system[%lf]\n", sP_power_cpu_user, sP_power_cpu_system);
901         /* CPU power consumption Level - 1 at the Resource Level */
902         long int P_power_cpu = 0, P_power_user = 0, P_power_system = 0;
903         uTime /= 1000; sTime /= 1000; onTime /= 1000;
904         P_power_user = ((sP_power_cpu_user * uTime));
905         P_power_system = ((sP_power_cpu_system * sTime));
906         P_power_cpu = P_power_user + P_power_system;
907
908         _DBG("Calculated Power for CPU P_power_cpu (%ld),  P_power_user (%ld), P_power_system (%ld)", P_power_cpu, P_power_user, P_power_system);
909         /* CPU power consumption Level - 2 at the Application Level */
910         GHashTableIter iter;
911         gpointer key, value;
912         g_hash_table_iter_init(&iter, hash);
913
914         long int P_power_app_cpu = 0, P_power_app_use = 0;
915         double apptime = 0;
916         char *appid = NULL;
917         long int ret_time = bm_get_log_time(data_collection_period);
918         long int total_app_pw = 0, base_res_pw = 0;
919
920         appid_usage_s app_usage;
921
922         while (g_hash_table_iter_next(&iter, &key, &value)) {
923                 P_power_app_cpu = 0; P_power_app_use = 0;
924                 apptime = 0;
925                 app_time_map_st1 *temp = (app_time_map_st1 *)value;
926                 appid = temp->app_id;
927                 apptime = (temp->time);
928                 apptime /= 1000;
929                 if (onTime != 0)
930                         P_power_app_use = (P_power_cpu * apptime)/onTime; //check for 0 denominator & same units
931                 P_power_app_cpu = P_power_app_use;
932
933                 app_usage.AppId = appid;
934                 app_usage.rId_cpu = P_power_app_cpu;
935                 app_usage.log_time = ret_time;
936                 total_app_pw += P_power_app_cpu;
937                 /* Call Insert Function */
938                 _DBG("Calculated Power for Appid (%s) P_power_app_cpu (%ld),  P_power_app_use (%ld)", appid, P_power_app_cpu, P_power_app_use);
939
940                 if (mode) {
941                         ret_val = bm_server_appid_insert_to_db(app_usage.AppId);
942                         if (ret_val != BATTERY_MONITOR_ERROR_NONE)
943                                 _ERR("Insert of CPU appid failed ");
944                         ret_val = bm_server_app_usage_insert_to_db(&app_usage);
945                 } else
946                         ret_val = bm_appid_session_usage_map(app_usage.AppId, app_usage.rId_cpu, BM_PLUGIN_ID_CPU);
947                 /* Error Check */
948                 if (ret_val != BATTERY_MONITOR_ERROR_NONE)
949                         _ERR("Insert of CPU App failed ");
950         }
951
952         resourceid_usage_s res_usage;
953
954         res_usage.ResourceId = BM_RID_CPU;
955         res_usage.log_time = ret_time;
956         res_usage.usage = P_power_cpu;
957         ret_val = bm_server_resource_usage_insert_to_db(&res_usage);
958         if (ret_val != BATTERY_MONITOR_ERROR_NONE)
959                 _ERR("Insert of CPU resource failed ");
960
961         if (P_power_cpu > total_app_pw) {
962                 base_res_pw = (P_power_cpu - total_app_pw);
963                 res_usage.usage = base_res_pw;
964                 ret_val = bm_server_resource_base_usage_insert_to_db(&res_usage);
965                 if (ret_val != BATTERY_MONITOR_ERROR_NONE)
966                         _ERR("Insert of CPU base resource failed ");
967         }
968
969         bd_gl_cpu_stat_s *gcpu_st = (bd_gl_cpu_stat_s *)calloc(1, sizeof(bd_gl_cpu_stat_s));
970         if (gcpu_st == NULL) {
971                 _ERR("memory allocation failed");
972                 return BATTERY_MONITOR_ERROR_OUT_OF_MEMORY;
973         }
974         gcpu_st->time_s = ret_time; gcpu_st->usr_time = uTime;
975         gcpu_st->sys_time = sTime;
976         ret_val = bm_server_battery_dump_insert_to_db(gcpu_st, 7);
977         if (ret_val != BATTERY_MONITOR_ERROR_NONE)
978                 _ERR("Insert GCPU failed");
979         BM_FREE(gcpu_st);
980         /* Free the Hash Map */
981         g_hash_table_destroy(hash);
982
983         EXIT;
984         return ret_val;
985 }
986
987 int bm_display_calc_power_and_commit(bm_display_st *handle, bool mode)
988 {
989         ENTER;
990
991         BM_CHECK_INPUT_PARAM(handle);
992
993         GSList *dp_data_iterator = NULL;
994         GSList *dp_atm_iterator = NULL;
995         void *prv_data = NULL;
996         void *prv_app_id = NULL;
997         int ret_val = BATTERY_MONITOR_ERROR_NONE;
998
999         /* creating hash-map with (key, value) = (app-id, data) */
1000         GHashTable *hash = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, NULL);
1001
1002         long int edTime = 0, stTime = 0, sesTime = 0;
1003         long int highTime = 0, medTime = 0, lowTime = 0;
1004         double onTime = 0;
1005         /* iterating over list for data accumulation */
1006         for (dp_data_iterator = handle->display_list; dp_data_iterator; dp_data_iterator = dp_data_iterator->next) {
1007                 bm_display_st *datalistnode = (bm_display_st *)(dp_data_iterator->data);
1008                 edTime = datalistnode->stop;
1009                 stTime = datalistnode->start;
1010                 highTime += datalistnode->high;
1011                 medTime += datalistnode->med;
1012                 lowTime += datalistnode->low;
1013                 sesTime += edTime - stTime;
1014                 dp_atm_iterator = datalistnode->atm_list;
1015                 for ( ; dp_atm_iterator; dp_atm_iterator = dp_atm_iterator->next) {
1016                         app_time_map_st1 *dp_atm_node = (app_time_map_st1 *)dp_atm_iterator->data;
1017                         if (!dp_atm_node) {
1018                                 _DBG("no data available");
1019                                 continue;
1020                         }
1021                         _DBG("display data available");
1022                         onTime += dp_atm_node->time;
1023                         prv_data = NULL;
1024                         prv_app_id = NULL;
1025                         if (g_hash_table_lookup_extended(hash, dp_atm_node->app_id, &prv_app_id, &prv_data) == true) {
1026                                 _DBG("previous app_id = %s", (char *)prv_app_id);
1027                                 app_time_map_st1 *dp_atm_prv_node = (app_time_map_st1 *)prv_data;
1028                                 dp_atm_node->time += dp_atm_prv_node->time;
1029                                 _DBG("update - app_id(%s), time(%d)", dp_atm_node->app_id, dp_atm_node->time);
1030                                 _INFO("updated - %d", g_hash_table_replace(hash, dp_atm_node->app_id, dp_atm_node));
1031                         } else {
1032                                 _DBG("insert - app_id(%s), time(%d)", dp_atm_node->app_id, dp_atm_node->time);
1033                                 _INFO("inserted - %d", g_hash_table_insert(hash, dp_atm_node->app_id, dp_atm_node));
1034                         }
1035                 }
1036         }
1037
1038         /* Read standard Rated Values from Device Spec File/Power Profile File */
1039         double sP_power_dp_low = 0, sP_power_dp_med = 0, sP_power_dp_high = 0;
1040
1041         ret_val = bm_get_display_power_params(&sP_power_dp_high, &sP_power_dp_med, &sP_power_dp_low);
1042         if (ret_val != BATTERY_MONITOR_ERROR_NONE)
1043                 _ERR("failed to get cpu power params");
1044
1045         _DBG("received display power params - high[%lf], medium[%lf], low[%lf]", sP_power_dp_high, sP_power_dp_med, sP_power_dp_low);
1046         /* Display power consumption Level - 1 at the Resource Level */
1047         lowTime /= 1000; medTime /= 1000; highTime /= 1000; onTime /= 1000;
1048         long int P_power_disp = 0, P_power_on = 0;
1049         P_power_on = ((sP_power_dp_low * lowTime) + (sP_power_dp_med * medTime) + (sP_power_dp_high * highTime));
1050         P_power_disp = P_power_on;
1051         _DBG("Calculated Power for Display P_power_disp (%ld),  P_power_on (%ld)", P_power_disp, P_power_on);
1052         /* Display power consumption Level - 2 at the Application Level */
1053         GHashTableIter iter;
1054         gpointer key, value;
1055         g_hash_table_iter_init(&iter, hash);
1056
1057         long int P_power_app_disp = 0, P_power_app_on = 0;
1058         char *appid = NULL;
1059         double apptime = 0;
1060         long int ret_time = bm_get_log_time(data_collection_period);
1061         long int total_app_pw = 0, base_res_pw = 0;
1062
1063         appid_usage_s app_usage;
1064
1065         while (g_hash_table_iter_next(&iter, &key, &value)) {
1066                 P_power_app_disp = 0; P_power_app_on = 0;
1067                 apptime = 0;
1068                 app_time_map_st1 *temp = (app_time_map_st1 *)value;
1069                 appid = temp->app_id;
1070                 apptime = temp->time;
1071                 apptime /= 1000;
1072                 if (onTime != 0)
1073                         P_power_app_on = (P_power_on * apptime)/onTime; //check for 0 denominator & same units
1074                 P_power_app_disp = P_power_app_on;
1075
1076                 app_usage.AppId = appid;
1077                 app_usage.rId_display = P_power_app_disp;
1078                 app_usage.log_time = ret_time;
1079                 total_app_pw += P_power_app_disp;
1080                 /* Call Insert Function */
1081                 _DBG("Calculated Power for Appid (%s) P_power_app_disp(%ld),  P_power_app_on (%ld)", appid, P_power_app_disp, P_power_app_on);
1082                 if (mode) {
1083                         ret_val = bm_server_appid_insert_to_db(app_usage.AppId);
1084                         if (ret_val != BATTERY_MONITOR_ERROR_NONE)
1085                                 _ERR("Insert of DSP appid failed ");
1086                         ret_val = bm_server_app_usage_insert_to_db(&app_usage);
1087                 } else
1088                         ret_val = bm_appid_session_usage_map(app_usage.AppId, app_usage.rId_display, BM_PLUGIN_ID_DISPLAY);
1089                 /* Error Check */
1090                 if (ret_val != BATTERY_MONITOR_ERROR_NONE)
1091                         _ERR("Insert of Display App failed ");
1092         }
1093
1094         /* commit to database the output after power calculation */
1095         resourceid_usage_s res_usage;
1096
1097         res_usage.ResourceId = BM_RID_DISP;
1098         res_usage.log_time = ret_time;
1099         res_usage.usage = P_power_disp;
1100         ret_val = bm_server_resource_usage_insert_to_db(&res_usage);
1101         if (ret_val != BATTERY_MONITOR_ERROR_NONE)
1102                 _ERR("Insert of Display resource failed ");
1103
1104         if (P_power_disp > total_app_pw) {
1105                 base_res_pw = (P_power_disp - total_app_pw);
1106                 res_usage.usage = base_res_pw;
1107                 ret_val = bm_server_resource_base_usage_insert_to_db(&res_usage);
1108                 if (ret_val != BATTERY_MONITOR_ERROR_NONE)
1109                         _ERR("Insert of Display base resource failed ");
1110         }
1111
1112         bd_gl_sbr_stat_s *gbr_st = (bd_gl_sbr_stat_s *)calloc(1, sizeof(bd_gl_sbr_stat_s));
1113         if (gbr_st == NULL) {
1114                 _ERR("memory allocation failed");
1115                 return BATTERY_MONITOR_ERROR_OUT_OF_MEMORY;
1116         }
1117
1118         gbr_st->time_s = ret_time; gbr_st->dark = (data_collection_period / 1000);
1119         gbr_st->dark -= sesTime; gbr_st->dim = lowTime; gbr_st->medium = medTime;
1120         gbr_st->bright = highTime;
1121
1122         ret_val = bm_server_battery_dump_insert_to_db(gbr_st, 3);
1123         if (ret_val != BATTERY_MONITOR_ERROR_NONE)
1124                 _ERR("Insert of GBR failed ");
1125         else
1126                 _DBG("Insert GBR successful");
1127         BM_FREE(gbr_st);
1128         /* Free the Hash Map */
1129         g_hash_table_destroy(hash);
1130
1131         EXIT;
1132         return ret_val;
1133 }
1134
1135 int bm_device_network_calc_power_and_commit(bm_device_network_st *handle, bool mode)
1136 {
1137         ENTER;
1138
1139         BM_CHECK_INPUT_PARAM(handle);
1140
1141         GSList *dn_data_iterator = NULL;
1142         GSList *dn_atm_iterator = NULL;
1143         void *prv_data = NULL;
1144         void *prv_app_id = NULL;
1145         int ret_val = BATTERY_MONITOR_ERROR_NONE;
1146
1147         /* creating hash-map with (key, value) = (app-id, data) */
1148         GHashTable *hash = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, NULL);
1149
1150         long int tl0 = 0, tl1 = 0, tl2 = 0, tl3 = 0, tl4 = 0, tl5 = 0, tl6 = 0;
1151         long int RX = 0, TX = 0;
1152         double tl_total = 0;
1153         /* iterating over list for data accumulation */
1154         for (dn_data_iterator = handle->dn_data_list; dn_data_iterator; dn_data_iterator = dn_data_iterator->next) {
1155                 bm_device_network_st *datalistnode = (bm_device_network_st *)(dn_data_iterator->data);
1156                 tl0 += datalistnode->time_level_0;
1157                 tl1 += datalistnode->time_level_1;
1158                 tl2 += datalistnode->time_level_2;
1159                 tl3 += datalistnode->time_level_3;
1160                 tl4 += datalistnode->time_level_4;
1161                 tl5 += datalistnode->time_level_5;
1162                 tl6 += datalistnode->time_level_6;
1163                 dn_atm_iterator = datalistnode->atm_list;
1164                 for ( ; dn_atm_iterator; dn_atm_iterator = dn_atm_iterator->next) {
1165                         app_time_map_st2 *dn_atm_node = (app_time_map_st2 *)dn_atm_iterator->data;
1166                         if (!dn_atm_node) {
1167                                 _DBG("no data available");
1168                                 continue;
1169                         }
1170                         _DBG("device-network data available");
1171                         RX += dn_atm_node->rx;
1172                         TX += dn_atm_node->tx;
1173                         prv_data = NULL;
1174                         prv_app_id = NULL;
1175                         if (g_hash_table_lookup_extended(hash, dn_atm_node->app_id, &prv_app_id, &prv_data) == true) {
1176                                 _DBG("previous app_id = %s", (char *)prv_app_id);
1177                                 app_time_map_st2 *dn_atm_prv_node = (app_time_map_st2 *)prv_data;
1178                                 dn_atm_node->time += dn_atm_prv_node->time;
1179                                 dn_atm_node->rx += dn_atm_prv_node->rx;
1180                                 dn_atm_node->tx += dn_atm_prv_node->tx;
1181                                 _DBG("update - app_id(%s), time(%d), rx(%d), tx(%d)", dn_atm_node->app_id,
1182                                                 dn_atm_node->time, dn_atm_node->rx, dn_atm_node->tx);
1183                                 _INFO("updated - %d", g_hash_table_replace(hash, dn_atm_node->app_id, dn_atm_node));
1184                         } else {
1185                                 _DBG("insert - app_id(%s), time(%d), rx(%d), tx(%d)", dn_atm_node->app_id,
1186                                                 dn_atm_node->time, dn_atm_node->rx, dn_atm_node->tx);
1187                                 _INFO("inserted - %d", g_hash_table_insert(hash, dn_atm_node->app_id, dn_atm_node));
1188                         }
1189                 }
1190         }
1191
1192         /* Read standard Rated Values from Device Spec File/Power Profile File */
1193         double sP_power_dn_tl0 = 0, sP_power_dn_tl1 = 0, sP_power_dn_tl2 = 0, sP_power_dn_tl3 = 0, sP_power_dn_tl4 = 0,
1194         sP_power_dn_tl5 = 0, sP_power_dn_tl6 = 0, sP_power_dn_tx = 0, sP_power_dn_rx = 0;
1195
1196         ret_val = bm_get_device_network_power_params(&sP_power_dn_tl0, &sP_power_dn_tl1, &sP_power_dn_tl2, &sP_power_dn_tl3,
1197                         &sP_power_dn_tl4, &sP_power_dn_tl5, &sP_power_dn_tl6, &sP_power_dn_rx, &sP_power_dn_tx);
1198         if (ret_val != BATTERY_MONITOR_ERROR_NONE)
1199                 _ERR("failed to get cpu power params");
1200         _DBG("received device-network power params - signal_0[%lf]\n, signal_1[%lf]\n, signal_2[%lf]\n, \
1201                         signal_3[%lf]\n, signal_4[%lf]\n, signal_5[%lf]\n, signal_6[%lf]\n, rx[%lf]\n, tx[%lf]\n",
1202                         sP_power_dn_tl0, sP_power_dn_tl1, sP_power_dn_tl2, sP_power_dn_tl3, sP_power_dn_tl4, sP_power_dn_tl5,
1203                         sP_power_dn_tl6, sP_power_dn_rx, sP_power_dn_tx);
1204
1205         tl0 /= 1000; tl1 /= 1000; tl2 /= 1000; tl3 /= 1000; tl4 /= 1000; tl5 /= 1000; tl6 /= 1000;
1206         tl_total = tl0 + tl1 + tl2 + tl3 + tl4 + tl5 + tl6;
1207         /* Device Network power consumption Level - 1 at the Resource Level */
1208         long int P_power_dntw = 0, P_power_data = 0, P_power_conn = 0;
1209         P_power_conn = ((sP_power_dn_tl0 * tl0) + (sP_power_dn_tl1 * tl1) + (sP_power_dn_tl2 * tl2) + (sP_power_dn_tl3 * tl3) + (sP_power_dn_tl4 * tl4) + (sP_power_dn_tl5 * tl5) + (sP_power_dn_tl6 * tl6));
1210         P_power_data = ((sP_power_dn_tx) * TX) + ((sP_power_dn_rx) * RX);
1211         P_power_dntw = P_power_conn + P_power_data;
1212
1213         _DBG("Calculated Power for Device Network P_power_ntw(%ld),  P_power_conn (%ld), P_power_data(%ld)", P_power_dntw, P_power_conn, P_power_data);
1214         /* Device Network power consumption Level - 2 at the Application Level */
1215         GHashTableIter iter;
1216         gpointer key, value;
1217         g_hash_table_iter_init(&iter, hash);
1218
1219         long int P_power_app_dntw = 0, P_power_app_data = 0, P_power_app_conn = 0;
1220         char *appid = NULL;
1221         long int apprx = 0, apptx = 0;
1222         double apptime = 0;
1223         long int ret_time = bm_get_log_time(data_collection_period);
1224         long int total_app_pw = 0, base_res_pw = 0;
1225
1226         appid_usage_s app_usage;
1227
1228         while (g_hash_table_iter_next(&iter, &key, &value)) {
1229                 P_power_app_dntw = 0; P_power_app_data = 0 ; P_power_app_conn = 0;
1230                 apprx = 0, apptx = 0, apptime = 0;
1231                 app_time_map_st2 *temp = (app_time_map_st2 *)value;
1232                 appid = temp->app_id;
1233                 apprx = temp->rx; apptx = temp->tx;
1234                 apptime = temp->time; apptime /= 1000;
1235                 P_power_app_data = ((sP_power_dn_tx) * apptx) + ((sP_power_dn_rx) * apprx);
1236                 if (tl_total != 0)
1237                         P_power_app_conn = (P_power_conn * apptime)/tl_total; //check for 0 denominator & same units
1238                 P_power_app_dntw = P_power_app_data + P_power_app_conn;
1239
1240                 app_usage.AppId = appid;
1241                 app_usage.rId_device_network = P_power_app_dntw;
1242                 app_usage.log_time = ret_time;
1243                 total_app_pw += P_power_app_dntw;
1244                 /* Call Insert Function */
1245                 _DBG("Calculated Power for Appid (%s) P_power_app_dntw(%ld),  P_power_app_conn (%ld), P_power_app_data(%ld)", appid, P_power_app_dntw, P_power_app_conn, P_power_app_data);
1246                 if (mode) {
1247                         ret_val = bm_server_appid_insert_to_db(app_usage.AppId);
1248                         if (ret_val != BATTERY_MONITOR_ERROR_NONE)
1249                                 _ERR("Insert of DN appid failed ");
1250                         ret_val = bm_server_app_usage_insert_to_db(&app_usage);
1251                 } else
1252                         ret_val = bm_appid_session_usage_map(app_usage.AppId, app_usage.rId_device_network, BM_PLUGIN_ID_DEVICE_NETWORK);
1253                 if (ret_val != BATTERY_MONITOR_ERROR_NONE)
1254                         _ERR("Insert of Data Ntwk App failed ");
1255         }
1256
1257         /* commit to database the output after power calculation */
1258         resourceid_usage_s res_usage;
1259
1260         res_usage.ResourceId = BM_RID_DNTW;
1261         res_usage.log_time = ret_time;
1262         res_usage.usage = P_power_dntw;
1263         ret_val = bm_server_resource_usage_insert_to_db(&res_usage);
1264         if (ret_val != BATTERY_MONITOR_ERROR_NONE)
1265                 _ERR("Insert of Data Network resource failed ");
1266
1267         if (P_power_dntw > total_app_pw) {
1268                 base_res_pw = (P_power_dntw - total_app_pw);
1269                 res_usage.usage = base_res_pw;
1270                 ret_val = bm_server_resource_base_usage_insert_to_db(&res_usage);
1271                 if (ret_val != BATTERY_MONITOR_ERROR_NONE)
1272                         _ERR("Insert of Data Network base resource failed ");
1273         }
1274
1275         bd_gl_sgt_stat_s *gst_st = (bd_gl_sgt_stat_s *)calloc(1, sizeof(bd_gl_sgt_stat_s));
1276         if (gst_st == NULL) {
1277                 _ERR("memory allocation failed");
1278                 return BATTERY_MONITOR_ERROR_OUT_OF_MEMORY;
1279         }
1280
1281         gst_st->time_s = ret_time; gst_st->scan_time = tl0; gst_st->none_time = tl1;
1282         gst_st->poor_time = tl2; gst_st->med_time = tl3 + tl4;
1283         gst_st->good_time = tl5; gst_st->grt_time = tl6;
1284         ret_val = bm_server_battery_dump_insert_to_db(gst_st, 4);
1285         if (ret_val != BATTERY_MONITOR_ERROR_NONE)
1286                 _ERR("Insert of GWFL failed ");
1287         BM_FREE(gst_st);
1288
1289         /* Free the Hash Map */
1290         g_hash_table_destroy(hash);
1291
1292         EXIT;
1293         return ret_val;
1294 }
1295
1296 #ifdef DISABLE_FEATURE_DATA_FROM_GPS_HRM_PLUGIN
1297 int bm_gps_calc_power_and_commit(bm_gps_st *handle)
1298 {
1299         ENTER;
1300
1301         BM_CHECK_INPUT_PARAM(handle);
1302
1303         GSList *gps_data_iterator = NULL;
1304         GSList *gps_atm_iterator = NULL;
1305         void *prv_data = NULL;
1306         void *prv_app_id = NULL;
1307         int ret_val = BATTERY_MONITOR_ERROR_NONE;
1308
1309         /* creating hash-map with (key, value) = (app-id, data) */
1310         GHashTable *hash = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, NULL);
1311
1312         long int edTime = 0;
1313         long int stTime = 0;
1314         int sesTime = 0;
1315         int onTime = 0;
1316         /* iterating over list for data accumulation */
1317         for (gps_data_iterator = handle->gps_data_list; gps_data_iterator; gps_data_iterator = gps_data_iterator->next) {
1318                 bm_gps_st *datalistnode = (bm_gps_st *)(gps_data_iterator->data);
1319                 edTime = datalistnode->connStartTime;
1320                 stTime = datalistnode->connStopTime;
1321                 sesTime = edTime - stTime;
1322                 gps_atm_iterator = datalistnode->atm_list;
1323                 for ( ; gps_atm_iterator; gps_atm_iterator = gps_atm_iterator->next) {
1324                         app_time_map_st1 *gps_atm_node = (app_time_map_st1 *)gps_atm_iterator->data;
1325                         if (!gps_atm_node) {
1326                                 _DBG("no bt data available");
1327                                 continue;
1328                         }
1329                         _DBG("gps data available");
1330                         onTime += gps_atm_node->time;
1331                         prv_app_id = NULL;
1332                         prv_data = NULL;
1333                         if (g_hash_table_lookup_extended(hash, gps_atm_node->app_id, &prv_app_id, &prv_data) == true) {
1334                                 _DBG("previous app_id = %s", (char *)prv_app_id);
1335                                 app_time_map_st1 *gps_atm_prv_node = (app_time_map_st1 *)prv_data;
1336                                 gps_atm_node->time += gps_atm_prv_node->time;
1337                                 _DBG("update - app_id(%s), time(%d)", gps_atm_node->app_id, gps_atm_node->time);
1338                                 _INFO("updated - %d", g_hash_table_replace(hash, gps_atm_node->app_id, gps_atm_node));
1339                         } else {
1340                                 _DBG("insert - app_id(%s), time(%d)", gps_atm_node->app_id, gps_atm_node->time);
1341                                 _INFO("inserted - %d", g_hash_table_insert(hash, gps_atm_node->app_id, gps_atm_node));
1342                         }
1343                 }
1344         }
1345
1346         /* Read standard Rated Values from Device Spec File/Power Profile File */
1347         double sP_power_gps_conn = 0;
1348
1349         ret_val = bm_get_gps_sensor_power_params(&sP_power_gps_conn);
1350         if (ret_val != BATTERY_MONITOR_ERROR_NONE)
1351                 _ERR("failed to get gps-sensor power params");
1352
1353         _DBG("gps-sensor power params - gps[%lf]", sP_power_gps_conn);
1354         /* GPS power consumption Level - 1 at the Resource Level */
1355         int P_power_gps = 0, P_power_conn = 0;
1356         P_power_conn = ((sP_power_gps_conn * sesTime));
1357
1358         P_power_gps = P_power_conn;
1359         _DBG("Calculated Power for GPS P_power_gps (%d),  P_power_conn (%d)", P_power_gps, P_power_conn);
1360
1361         /* GPS power consumption Level - 2 at the Application Level */
1362         GHashTableIter iter;
1363         gpointer key, value;
1364         g_hash_table_iter_init(&iter, hash);
1365
1366         int P_power_app_gps = 0, P_power_app_conn = 0;
1367         char *appid = NULL;
1368         int apptime = 0;
1369         long int ret_time = bm_get_log_time(data_collection_period);
1370         long int total_app_pw = 0, base_res_pw = 0;
1371
1372         appid_usage_s app_usage;
1373
1374         while (g_hash_table_iter_next(&iter, &key, &value)) {
1375                 P_power_app_gps = 0; P_power_app_conn = 0;
1376                 apptime = 0;
1377                 app_time_map_st1 *temp = (app_time_map_st1 *)value;
1378                 appid = temp->app_id; apptime = temp->time;
1379
1380                 if (onTime != 0)
1381                         P_power_app_conn = (P_power_conn * apptime)/onTime; //check for 0 denominator & same units
1382                 P_power_app_gps = P_power_app_conn;
1383
1384                 app_usage.AppId = appid;
1385                 app_usage.rId_gps = P_power_app_gps;
1386                 app_usage.log_time = ret_time;
1387                 total_app_pw += P_power_app_gps;
1388                 /* Call Insert Function */
1389                 _DBG("Calculated Power for Appid (%s) P_power_app_gps (%d),  P_power_app_conn (%d)", appid, P_power_app_gps, P_power_app_conn);
1390                 ret_val = bm_server_app_usage_insert_to_db(&app_usage);
1391                 if (ret_val != BATTERY_MONITOR_ERROR_NONE)
1392                         _ERR("Insert of GPS App failed ");
1393         }
1394
1395         /* commit to database the output after power calculation */
1396         resourceid_usage_s res_usage;
1397
1398         res_usage.ResourceId = BM_RID_GPS;
1399         res_usage.log_time = ret_time;
1400         res_usage.usage = P_power_gps;
1401         ret_val = bm_server_resource_usage_insert_to_db(&res_usage);
1402         if (ret_val != BATTERY_MONITOR_ERROR_NONE)
1403                 _ERR("Insert of GPS resource failed ");
1404
1405         if (P_power_gps > total_app_pw) {
1406                 base_res_pw = (P_power_gps - total_app_pw);
1407                 res_usage.usage = base_res_pw;
1408                 ret_val = bm_server_resource_base_usage_insert_to_db(&res_usage);
1409                 if (ret_val != BATTERY_MONITOR_ERROR_NONE)
1410                         _ERR("Insert of GPS base resource failed ");
1411         }
1412
1413         /* Free the Hash Map */
1414         g_hash_table_destroy(hash);
1415
1416         EXIT;
1417         return ret_val;
1418 }
1419
1420 int bm_hrm_calc_power_and_commit(bm_hrm_sensor_st *handle)
1421 {
1422         ENTER;
1423
1424         BM_CHECK_INPUT_PARAM(handle);
1425
1426         GSList *hrm_data_iterator = NULL;
1427         GSList *hrm_atm_iterator = NULL;
1428
1429         void *prv_data = NULL;
1430         void *prv_app_id = NULL;
1431
1432         int ret_val = BATTERY_MONITOR_ERROR_NONE;
1433
1434         /* creating hash-map with (key, value) = (app-id, data) */
1435         GHashTable *hash = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, NULL);
1436
1437         /* iterating over list for data accumulation */
1438         for (hrm_data_iterator = handle->hrm_data_list; hrm_data_iterator; hrm_data_iterator = hrm_data_iterator->next) {
1439
1440                 hrm_atm_iterator = ((bm_hrm_sensor_st *)(hrm_data_iterator->data))->atm_list;
1441
1442                 for ( ; hrm_atm_iterator; hrm_atm_iterator = hrm_atm_iterator->next) {
1443
1444                         app_time_map_st1 *hrm_atm_node = (app_time_map_st1 *)hrm_atm_iterator->data;
1445
1446                         if (!hrm_atm_node) {
1447                                 _DBG("no bt data available");
1448                                 continue;
1449                         }
1450
1451                         _DBG("hrm data available");
1452
1453                         prv_data = NULL;
1454                         prv_app_id = NULL;
1455
1456                         if (g_hash_table_lookup_extended(hash, hrm_atm_node->app_id, &prv_app_id, &prv_data) == true) {
1457
1458                                 _DBG("previous app_id = %s", (char *)prv_app_id);
1459
1460                                 app_time_map_st1 *hrm_atm_prv_node = (app_time_map_st1 *)prv_data;
1461
1462                                 hrm_atm_node->time += hrm_atm_prv_node->time;
1463
1464                                 _DBG("update - app_id(%s), time(%d)", hrm_atm_node->app_id, hrm_atm_node->time);
1465
1466                                 _INFO("updated - %d", g_hash_table_replace(hash, hrm_atm_node->app_id, hrm_atm_node));
1467
1468                         } else {
1469
1470                                 _DBG("insert - app_id(%s), time(%d)", hrm_atm_node->app_id, hrm_atm_node->time);
1471
1472                                 _INFO("inserted - %d", g_hash_table_insert(hash, hrm_atm_node->app_id, hrm_atm_node));
1473                         }
1474                 }
1475         }
1476
1477         double sP_power_hrm_conn = 0;
1478
1479         /* read hrm-sensor power params */
1480         ret_val = bm_get_hrm_sensor_power_params(&sP_power_hrm_conn);
1481         if (ret_val != BATTERY_MONITOR_ERROR_NONE)
1482                 _ERR("failed to get hrm-sensor power params");
1483
1484         _DBG("hrm-sensor power params - gps[%lf]", sP_power_hrm_conn);
1485
1486         /* apply power calculation on the hash-map data*/
1487
1488         /* commit to database the output after power calculation */
1489
1490         /* Free the Hash Map */
1491         g_hash_table_destroy(hash);
1492
1493         EXIT;
1494         return ret_val;
1495 }
1496 #endif /* DISABLE_FEATURE_DATA_FROM_GPS_HRM_PLUGIN */
1497
1498 int bm_battery_calc_power_and_commit(void)
1499 {
1500         ENTER;
1501
1502         int ret_val = DEVICE_ERROR_NONE;
1503         int battery_percent = 0;
1504         bool is_charging = false;
1505
1506         ret_val = device_battery_get_percent(&battery_percent);
1507         BM_RETURN_VAL((ret_val == DEVICE_ERROR_NONE), {},
1508                 BATTERY_MONITOR_ERROR_INTERNAL, "failed to get battery percent");
1509
1510         ret_val = device_battery_is_charging(&is_charging);
1511         BM_RETURN_VAL((ret_val == DEVICE_ERROR_NONE), {},
1512                 BATTERY_MONITOR_ERROR_INTERNAL, "failed to get charging status");
1513
1514         device_battery_level_e battery_level;
1515         ret_val = device_battery_get_level_status(&battery_level);
1516         BM_RETURN_VAL((ret_val == DEVICE_ERROR_NONE), {},
1517                 BATTERY_MONITOR_ERROR_INTERNAL, "failed to get warning status");
1518
1519         switch (battery_level) {
1520         case DEVICE_BATTERY_LEVEL_EMPTY:
1521                 _DBG("battery level - EMPTY");
1522                 break;
1523         case DEVICE_BATTERY_LEVEL_CRITICAL:
1524                 _DBG("battery level - CRITICAL");
1525                 break;
1526         case DEVICE_BATTERY_LEVEL_LOW:
1527                 _DBG("battery level - LOW");
1528                 break;
1529         case DEVICE_BATTERY_LEVEL_HIGH:
1530                 _DBG("battery level - HIGH");
1531                 break;
1532         case DEVICE_BATTERY_LEVEL_FULL:
1533                 _DBG("battery level - FULL");
1534                 break;
1535         default:
1536                 _DBG("invalid battery-level");
1537                 break;
1538         }
1539
1540         _INFO("battery percent[%d] & charging status[%s]",
1541                 battery_percent, (is_charging == true) ? "TRUE" : "FALSE");
1542
1543         int sP_power_battery = 0;
1544
1545         ret_val = bm_get_battery_power_params(&sP_power_battery);
1546         if (ret_val != BATTERY_MONITOR_ERROR_NONE)
1547                 _ERR("failed to get battery power params");
1548
1549         _DBG("received battery power params - battery[%d]", sP_power_battery);
1550
1551         ret_val = BATTERY_MONITOR_ERROR_NONE;
1552
1553         EXIT;
1554         return ret_val;
1555 }
1556
1557 int bm_get_data_from_handles(void)
1558 {
1559         ENTER;
1560
1561         BM_CHECK_INPUT_PARAM(bm_data_handle);
1562         BM_CHECK_INPUT_PARAM(bm_req_flag_h);
1563
1564         int ret_val = BATTERY_MONITOR_ERROR_NONE;
1565         bool mode = false;
1566
1567         gl_hash = g_hash_table_new_full(g_str_hash, g_str_equal, bm_data_free, bm_atm_free);
1568         if (!gl_hash)
1569                 _ERR("Global Hash creation failed");
1570
1571         /* parsing ble data */
1572         if (bm_data_handle->bm_ble_handle != NULL && bm_req_flag_h->req_ble_data) {
1573                 _DBG("parsing ble data");
1574                 ret_val = bm_ble_calc_power_and_commit(bm_data_handle->bm_ble_handle, mode);
1575                 BM_CHECK_VAL((ret_val == BATTERY_MONITOR_ERROR_NONE), "ble power cal failure");
1576         } else {
1577                 _DBG("set ble flag - true");
1578                 bm_engine_set_req_flag_handle(BM_PLUGIN_ID_BLE, true);
1579         }
1580         _DBG("completed ble data request");
1581
1582         /* parsing wifi data */
1583         if (bm_data_handle->bm_wifi_handle != NULL && bm_req_flag_h->req_wifi_data) {
1584                 _DBG("parsing wifi data");
1585                 ret_val = bm_wifi_calc_power_and_commit(bm_data_handle->bm_wifi_handle, mode);
1586                 BM_CHECK_VAL((ret_val == BATTERY_MONITOR_ERROR_NONE), "wifi power calc failure");
1587         } else {
1588                 _DBG("set wifi flag - true");
1589                 bm_engine_set_req_flag_handle(BM_PLUGIN_ID_WIFI, true);
1590         }
1591         _DBG("completed wifi data request");
1592
1593         /* parsing cpu data */
1594         if (bm_data_handle->bm_cpu_handle != NULL && bm_req_flag_h->req_cpu_data) {
1595                 _DBG("parsing cpu data");
1596                 ret_val = bm_cpu_calc_power_and_commit(bm_data_handle->bm_cpu_handle, mode);
1597                 BM_CHECK_VAL((ret_val == BATTERY_MONITOR_ERROR_NONE), "cpu power calc failure");
1598         } else {
1599                 _DBG("set cpu flag - true");
1600                 bm_engine_set_req_flag_handle(BM_PLUGIN_ID_CPU, true);
1601         }
1602         _DBG("completed cpu data request");
1603
1604         /* parsing display data */
1605         if (bm_data_handle->bm_display_handle != NULL && bm_req_flag_h->req_dp_data) {
1606                 _DBG("parsing display data");
1607                 ret_val = bm_display_calc_power_and_commit(bm_data_handle->bm_display_handle, mode);
1608                 BM_CHECK_VAL((ret_val == BATTERY_MONITOR_ERROR_NONE), "display power calc failure");
1609         } else {
1610                 _DBG("set display flag - true");
1611                 bm_engine_set_req_flag_handle(BM_PLUGIN_ID_DISPLAY, true);
1612         }
1613         _DBG("completed display data request");
1614
1615         /* parsing device-network data */
1616         if (bm_data_handle->bm_dn_handle != NULL && bm_req_flag_h->req_dn_data) {
1617                 _DBG("parsing device-network data");
1618                 ret_val = bm_device_network_calc_power_and_commit(bm_data_handle->bm_dn_handle, mode);
1619                 BM_CHECK_VAL((ret_val == BATTERY_MONITOR_ERROR_NONE), "device-network power calc failure");
1620         } else {
1621                 _DBG("set device-network flag - true");
1622                 bm_engine_set_req_flag_handle(BM_PLUGIN_ID_DEVICE_NETWORK, true);
1623         }
1624         _DBG("completed device-network data request");
1625
1626 #ifdef DISABLE_FEATURE_DATA_FROM_GPS_HRM_PLUGIN
1627         /* parsing gps data */
1628         if (bm_data_handle->bm_gps_handle != NULL && bm_req_flag_h->req_gps_data) {
1629                 _DBG("parsing gps data");
1630                 ret_val = bm_gps_calc_power_and_commit(bm_data_handle->bm_gps_handle);
1631                 BM_CHECK_VAL((ret_val == BATTERY_MONITOR_ERROR_NONE), "gps-sensor power calc failure");
1632         } else {
1633                 _DBG("set gps-sensor flag - true");
1634                 bm_engine_set_req_flag_handle(BM_PLUGIN_ID_GPS_SENSOR, true);
1635         }
1636         _DBG("completed gps data request");
1637
1638         /* parsing hrm data */
1639         if (bm_data_handle->bm_hrm_handle != NULL && bm_req_flag_h->req_hrm_data) {
1640                 _DBG("parsing hrm data");
1641                 ret_val = bm_hrm_calc_power_and_commit(bm_data_handle->bm_hrm_handle);
1642                 BM_CHECK_VAL((ret_val == BATTERY_MONITOR_ERROR_NONE), "hrm-sensor power calc failure");
1643         } else {
1644                 _DBG("set hrm-sensor flag - true");
1645                 bm_engine_set_req_flag_handle(BM_PLUGIN_ID_HRM_SENSOR, true);
1646         }
1647         _DBG("completed hrm data request");
1648 #endif /* DISABLE_FEATURE_DATA_FROM_GPS_HRM_PLUGIN */
1649
1650         /* parsing battery data */
1651         _DBG("parsing battery data");
1652         ret_val = bm_battery_calc_power_and_commit();
1653         BM_CHECK_VAL((ret_val == BATTERY_MONITOR_ERROR_NONE), "battery power calc failure");
1654         _DBG("completed battery data request");
1655
1656         ret_val = bm_insert_appid_session_usage_to_db();
1657         BM_CHECK_VAL((ret_val == BATTERY_MONITOR_ERROR_NONE), "battery session logging failure");
1658
1659         /* set free all the data handles */
1660         if (bm_data_handle != NULL) {
1661                 _DBG("Call Handle Free");
1662                 bm_set_free_data_handles(&bm_data_handle);
1663         }
1664
1665         /* set free global hash values */
1666         if (gl_hash) {
1667                 g_hash_table_destroy(gl_hash);
1668                 gl_hash = NULL;
1669         }
1670
1671         EXIT;
1672         return BATTERY_MONITOR_ERROR_NONE;
1673 }
1674
1675 int bm_start_getting_feature_data(void)
1676 {
1677         ENTER;
1678
1679         int ret_val = BATTERY_MONITOR_ERROR_NONE;
1680         int id;
1681         bm_plugin_info_h *bm_plugin = NULL;
1682         bm_data_h handle = NULL;
1683
1684         /* allocate  data & flag handle */
1685         if (bm_data_handle == NULL) {
1686                 bm_data_handle = (bm_feature_data_h)calloc(1, sizeof(struct bm_feature_data_handles_s));
1687                 if (!bm_data_handle) {
1688                         _ERR("memory allocation failed - data handle");
1689                         return BATTERY_MONITOR_ERROR_OUT_OF_MEMORY;
1690                 }
1691         }
1692
1693         bm_update_plugin_request_time();
1694
1695         /* request data from each plugin & store its handle */
1696 #ifdef DISABLE_FEATURE_DATA_FROM_GPS_HRM_PLUGIN
1697         for (id = BM_PLUGIN_ID_BLE; id < BM_PLUGIN_ID_MAX; ++id) {
1698 #else
1699         for (id = BM_PLUGIN_ID_BLE; id <= BM_PLUGIN_ID_DEVICE_NETWORK; ++id) {
1700 #endif
1701                 bm_get_feature_plugin_handle(&bm_plugin, id);
1702                 handle = NULL;
1703                 if (!bm_plugin || !bm_plugin->api) {
1704                         _WARN("Plugin with ID: %s is NULL", bm_get_plugin_name(id));
1705                         continue;
1706                 }
1707                 _INFO(" requesting data from plugin - %s", bm_get_plugin_name(id));
1708
1709                 switch (id) {
1710                 case BM_PLUGIN_ID_BLE: /* BLE Data */
1711                         ret_val = bm_plugin->api->get_feature_data(&handle, id);
1712                         if (ret_val != BATTERY_MONITOR_ERROR_NONE) {
1713                                 _DBG("ble data not available : improper value");
1714                                 handle = NULL;
1715                         }
1716                         if (handle != NULL) {
1717                                 _DBG("received ble data handle");
1718                                 bm_data_handle->bm_ble_handle = (bm_bluetooth_st *)(handle);
1719                         }
1720                         break;
1721                 case BM_PLUGIN_ID_WIFI: /* WI-FI Data */
1722                         ret_val = bm_plugin->api->get_feature_data(&handle, id);
1723                         if (ret_val != BATTERY_MONITOR_ERROR_NONE) {
1724                                 _DBG("wifi data not available : improper value");
1725                                 handle = NULL;
1726                         }
1727                         if (handle != NULL) {
1728                                 _DBG("received wifi data handle");
1729                                 bm_data_handle->bm_wifi_handle = (bm_wifi_st *)(handle);
1730                         }
1731                         break;
1732                 case BM_PLUGIN_ID_CPU: /* CPU Data */
1733                         ret_val = bm_plugin->api->get_feature_data(&handle, id);
1734                         if (ret_val != BATTERY_MONITOR_ERROR_NONE) {
1735                                 _DBG("cpu data not available : improper value");
1736                                 handle = NULL;
1737                         }
1738                         if (handle != NULL) {
1739                                 _DBG("received cpu data handle");
1740                                 bm_data_handle->bm_cpu_handle = (bm_cpu_st *)(handle);
1741                         }
1742                         break;
1743                 case BM_PLUGIN_ID_DISPLAY: /* DISPLAY Data */
1744                         ret_val = bm_plugin->api->get_feature_data(&handle, id);
1745                         if (ret_val != BATTERY_MONITOR_ERROR_NONE) {
1746                                 _DBG("display data not available : improper value");
1747                                 handle = NULL;
1748                         }
1749                         if (handle != NULL) {
1750                                 _DBG("received display data handle");
1751                                 bm_data_handle->bm_display_handle = (bm_display_st *)(handle);
1752                         }
1753                         break;
1754                 case BM_PLUGIN_ID_DEVICE_NETWORK: /* DEVICE-NETWORK Data */
1755                         ret_val = bm_plugin->api->get_feature_data(&handle, id);
1756                         if (ret_val != BATTERY_MONITOR_ERROR_NONE) {
1757                                 _DBG("device-network data not available : improper value");
1758                                 handle = NULL;
1759                         }
1760                         if (handle != NULL) {
1761                                 _DBG("received device network data handle");
1762                                 bm_data_handle->bm_dn_handle = (bm_device_network_st *)(handle);
1763                         }
1764                         break;
1765 #ifdef DISABLE_FEATURE_DATA_FROM_GPS_HRM_PLUGIN
1766                 case BM_PLUGIN_ID_GPS_SENSOR: /* GPS Sensor Data */
1767                         ret_val = bm_plugin->api->get_feature_data(&handle, id);
1768                         if (ret_val != BATTERY_MONITOR_ERROR_NONE) {
1769                                 _DBG("gps data not available : improper value");
1770                                 handle = NULL;
1771                         }
1772                         if (handle != NULL) {
1773                                 _DBG("received gps data handle");
1774                                 bm_data_handle->bm_gps_handle = (bm_gps_st *)(handle);
1775                         }
1776                         break;
1777                 case BM_PLUGIN_ID_HRM_SENSOR: /* HRM Sensor Data */
1778                         ret_val = bm_plugin->api->get_feature_data(&handle, id);
1779                         if (ret_val != BATTERY_MONITOR_ERROR_NONE) {
1780                                 _DBG("hrm data not available : improper value");
1781                                 handle = NULL;
1782                         }
1783                         if (handle != NULL) {
1784                                 _DBG("received hrm data handle");
1785                                 bm_data_handle->bm_hrm_handle = (bm_hrm_sensor_st *)(handle);
1786                         }
1787                         break;
1788 #endif /* DISABLE_FEATURE_DATA_FROM_GPS_HRM_PLUGIN */
1789                 default:
1790                         break;
1791                 }
1792         }
1793
1794         EXIT;
1795         return ret_val;
1796 }
1797
1798 int bm_clean_db_table_for_job_id(void)
1799 {
1800         ENTER;
1801
1802         int ret_val = BATTERY_MONITOR_ERROR_NONE;
1803
1804         ret_val = bm_server_delete_table_by_time_interval();
1805
1806         BM_RETURN_VAL((ret_val == BATTERY_MONITOR_ERROR_NONE), {},
1807                         BATTERY_MONITOR_ERROR_DB_FAILED, "error in deleting old db data");
1808
1809         EXIT;
1810         return ret_val;
1811 }
1812
1813 /**
1814  * We don't use idle time because it can be decreased
1815  * when CPU core is inactive.
1816  *
1817  * Instead, we will use uptime to calculate CPU usage
1818  * CPU_USAGE = (CT_USER + CT_NICE + CT_SYSTEM) / (NUM_CORE * UPTIME)
1819  */
1820 enum cpu_time {
1821         CT_USER = 0,
1822         CT_NICE,
1823         CT_SYSTEM,
1824 //      CT_IDLE,
1825         CT_NUM
1826 };
1827
1828 static int data_collection_try_period = 1000;
1829 static int data_collection_accept_count = 5;
1830 static double up_time_last;
1831 static unsigned long long cpu_time_last[CT_NUM];
1832
1833 int bm_get_cpu_time(unsigned long long cpu_time[CT_NUM])
1834 {
1835         int ret_val = 0;
1836         FILE *fp = NULL;
1837
1838         fp = fopen("/proc/stat", "r");
1839         if (!fp) {
1840                 _ERR("fopen failed : %m");
1841                 return BATTERY_MONITOR_ERROR_NO_DATA;
1842         }
1843
1844         ret_val = fscanf(fp, "%*s %llu %llu %llu", &cpu_time[CT_USER], &cpu_time[CT_NICE], &cpu_time[CT_SYSTEM]);
1845         fclose(fp);
1846
1847         if (ret_val < CT_NUM) {
1848                 _ERR("fscanf failed : %m");
1849                 return BATTERY_MONITOR_ERROR_NO_DATA;
1850         }
1851
1852         return BATTERY_MONITOR_ERROR_NONE;
1853 }
1854
1855 int bm_get_up_time(double *up_time)
1856 {
1857         int ret_val = 0;
1858         FILE *fp = NULL;
1859
1860         fp = fopen("/proc/uptime", "r");
1861         if (!fp) {
1862                 _ERR("fopen failed : %m");
1863                 return BATTERY_MONITOR_ERROR_NO_DATA;
1864         }
1865
1866         ret_val = fscanf(fp, "%lf", up_time);
1867         fclose(fp);
1868
1869         if (ret_val < 1) {
1870                 _ERR("fscanf failed : %m");
1871                 return BATTERY_MONITOR_ERROR_NO_DATA;
1872         }
1873
1874         return BATTERY_MONITOR_ERROR_NONE;
1875 }
1876
1877 gboolean is_cpu_idle(double usage_ratio_threshold)
1878 {
1879         static int num_cpu_core = -1;
1880
1881         int idx;
1882         unsigned long long cpu_time_cur[CT_NUM];
1883         unsigned long long cpu_time_diff[CT_NUM];
1884         double up_time_cur;
1885         double up_time_diff;
1886         double usage_ratio;
1887
1888         if (num_cpu_core < 0) {
1889                 if (runtime_info_get_processor_count(&num_cpu_core) != RUNTIME_INFO_ERROR_NONE) {
1890                         _ERR("error getting the number of cpu core");
1891                         return FALSE;
1892                 }
1893         }
1894
1895         // Get CPU time
1896         if (bm_get_cpu_time(cpu_time_cur) != BATTERY_MONITOR_ERROR_NONE) {
1897                 _ERR("error getting CPU time");
1898                 return FALSE;
1899         }
1900
1901         for (idx = 0; idx < CT_NUM; idx++) {
1902                 if (cpu_time_last[idx] > cpu_time_cur[idx]) {
1903                         _ERR("error invalid CPU time");
1904                         return FALSE;
1905                 }
1906                 cpu_time_diff[idx] = cpu_time_cur[idx] - cpu_time_last[idx];
1907         }
1908
1909         for (idx = 0; idx < CT_NUM; idx++)
1910                 cpu_time_last[idx] = cpu_time_cur[idx];
1911
1912         // Get uptime
1913         if (bm_get_up_time(&up_time_cur) != BATTERY_MONITOR_ERROR_NONE) {
1914                 _ERR("error getting uptime");
1915                 return FALSE;
1916         }
1917
1918         if (up_time_last >= up_time_cur) {
1919                 _ERR("error invalid uptime");
1920                 return FALSE;
1921         }
1922
1923         up_time_diff = up_time_cur - up_time_last;
1924         up_time_last = up_time_cur;
1925
1926         // Calculate CPU usage
1927         usage_ratio = ((double)cpu_time_diff[CT_USER] + cpu_time_diff[CT_NICE] + cpu_time_diff[CT_SYSTEM]) / (up_time_diff * num_cpu_core * 100);
1928         if (usage_ratio > 1.0)
1929                 usage_ratio = 1.0;
1930         if (usage_ratio > usage_ratio_threshold) {
1931                 _WARN("CPU usage = %.2lf%% (BUSY, criteria[%.2lf%%])", usage_ratio * 100, usage_ratio_threshold * 100);
1932                 return FALSE;
1933         }
1934
1935         _DBG("CPU usage = %.2lf%% (IDLE, criteria[%.2lf%%])", usage_ratio * 100, usage_ratio_threshold * 100);
1936         return TRUE;
1937 }
1938
1939 gboolean bm_try_request_feature_data(gpointer data)
1940 {
1941         enum status {
1942                 GET_DATA = 0,
1943                 CALC_AND_STORE,
1944         };
1945
1946         static gboolean is_parameter_loaded = FALSE;
1947         static int timeout = 60000;
1948         static double initial_threshold = 0.60;
1949         static double maximum_threshold = 0.70;
1950         static double threshold_variance = 0.0;
1951
1952         static int remaining_timeout = 60000;
1953         static double usage_ratio_threshold = 0.60;
1954
1955         static enum status status = GET_DATA;
1956         static int idle_count = 0;
1957         int ret_val;
1958
1959         if (!is_parameter_loaded) {
1960                 if (bm_get_cpu_usage_checker_params(&timeout, &initial_threshold, &maximum_threshold, &threshold_variance) != BATTERY_MONITOR_ERROR_NONE) {
1961                         _ERR("error getting cpu usage checker parameters");
1962                         return G_SOURCE_REMOVE;
1963                 }
1964                 remaining_timeout = timeout;
1965                 usage_ratio_threshold = initial_threshold;
1966
1967                 is_parameter_loaded = TRUE;
1968         }
1969
1970         if (remaining_timeout <= 0) {
1971                 _DBG("timeout!");
1972                 goto request;
1973         }
1974         remaining_timeout -= data_collection_try_period;
1975
1976         if (!is_cpu_idle(usage_ratio_threshold)) {
1977                 idle_count = 0;
1978                 if (usage_ratio_threshold < maximum_threshold)
1979                         usage_ratio_threshold += threshold_variance;
1980
1981                 return G_SOURCE_CONTINUE;
1982         }
1983
1984         idle_count++;
1985         if (usage_ratio_threshold > initial_threshold)
1986                 usage_ratio_threshold -= threshold_variance;
1987
1988         _DBG("Idle count(%d/%d)", idle_count, data_collection_accept_count);
1989         if (idle_count < data_collection_accept_count)
1990                 return G_SOURCE_CONTINUE;
1991
1992 request:
1993         idle_count = 0;
1994         remaining_timeout = timeout;
1995         usage_ratio_threshold = initial_threshold;
1996
1997         switch (status) {
1998         case GET_DATA:  // Request data to plugin
1999                 ret_val = bm_start_getting_feature_data();
2000                 if (ret_val != BATTERY_MONITOR_ERROR_NONE) {
2001                         _ERR("error requesting feature data");
2002                         return G_SOURCE_CONTINUE;
2003                 }
2004
2005                 status = CALC_AND_STORE;
2006                 return G_SOURCE_CONTINUE;
2007         case CALC_AND_STORE:    // Calculate power consumption and restore to DB
2008                 ret_val = bm_get_data_from_handles();
2009                 if (ret_val != BATTERY_MONITOR_ERROR_NONE) {
2010                         _ERR("error in parsing data from handles");
2011                         return G_SOURCE_CONTINUE;
2012                 }
2013
2014                 status = GET_DATA;
2015                 return G_SOURCE_REMOVE;
2016         default:
2017                 _ERR("error invalid status");
2018                 status = GET_DATA;
2019                 return G_SOURCE_CONTINUE;
2020         }
2021 }
2022
2023 gboolean bm_request_feature_data(gpointer data)
2024 {
2025         ENTER;
2026
2027         int ret_val;
2028
2029         ret_val = bm_get_cpu_time(cpu_time_last);
2030         if (ret_val != BATTERY_MONITOR_ERROR_NONE) {
2031                 _ERR("error getting cpu time");
2032                 return G_SOURCE_CONTINUE;
2033         }
2034
2035         ret_val = bm_get_up_time(&up_time_last);
2036         if (ret_val != BATTERY_MONITOR_ERROR_NONE) {
2037                 _ERR("error getting uptime");
2038                 return G_SOURCE_CONTINUE;
2039         }
2040
2041         g_timeout_add(data_collection_try_period, bm_try_request_feature_data, NULL);
2042
2043         EXIT;
2044         return G_SOURCE_CONTINUE;
2045 }
2046
2047 gboolean bm_delete_data_from_db(gpointer data)
2048 {
2049         ENTER;
2050
2051         int ret_val = BATTERY_MONITOR_ERROR_NONE;
2052
2053         ret_val = bm_clean_db_table_for_job_id();
2054         if (ret_val != BATTERY_MONITOR_ERROR_NONE)
2055                 _ERR("error cleaning database");
2056
2057         EXIT;
2058         return G_SOURCE_CONTINUE;
2059 }
2060
2061 int initialize_power_engine(void)
2062 {
2063         ENTER;
2064
2065         int ret_val = BATTERY_MONITOR_ERROR_NONE;
2066         int delete_db_period = 86400000;
2067
2068         bm_req_flag_h = (struct bm_req_feature_data_handle_flag_s *)
2069                         calloc(1, sizeof(struct bm_req_feature_data_handle_flag_s));
2070         if (!bm_req_flag_h) {
2071                 _ERR("memory allocation failed - requet flag handle");
2072                 return BATTERY_MONITOR_ERROR_OUT_OF_MEMORY;
2073         }
2074
2075         bm_set_req_flag_handles(true);
2076
2077         ret_val = bm_get_job_scheduler_params(&data_collection_period, &data_collection_try_period, &data_collection_accept_count, &delete_db_period);
2078         if (ret_val != BATTERY_MONITOR_ERROR_NONE) {
2079                 _ERR("error getting job scheduler parameters");
2080                 return ret_val;
2081         }
2082
2083         BM_RETURN_VAL((data_collection_period > 0), {}, BATTERY_MONITOR_ERROR_INVALID_PARAMETER, "invalid data collection period");
2084         BM_RETURN_VAL((data_collection_try_period > 0), {}, BATTERY_MONITOR_ERROR_INVALID_PARAMETER, "invalid data collection try period");
2085         BM_RETURN_VAL((data_collection_accept_count > 0), {}, BATTERY_MONITOR_ERROR_INVALID_PARAMETER, "invalid data collection accept count");
2086         BM_RETURN_VAL((delete_db_period > 0), {}, BATTERY_MONITOR_ERROR_INVALID_PARAMETER, "invalid delete db period");
2087
2088         gtimeo_id[0] = 0; gtimeo_id[1] = 0;
2089         gtimeo_id[0] = g_timeout_add(data_collection_period, bm_request_feature_data, NULL);
2090         gtimeo_id[1] = g_timeout_add(delete_db_period, bm_delete_data_from_db, NULL);
2091         _DBG("timeout with id %d and %d added", gtimeo_id[0], gtimeo_id[1]);
2092
2093         ret_val = bm_clean_db_table_for_job_id();
2094         if (ret_val != BATTERY_MONITOR_ERROR_NONE)
2095                 _ERR("error cleaning database");
2096
2097         ret_val = bm_get_battery_power_params(&battery_capacity);
2098         if (ret_val != BATTERY_MONITOR_ERROR_NONE)
2099                 _ERR("unable ro read battery capacity");
2100         battery_capacity *= cmah; //Battery Capacity in mAs
2101
2102         bm_update_plugin_request_time();
2103
2104         EXIT;
2105         return ret_val;
2106 }
2107
2108 void deinitialize_power_engine(void)
2109 {
2110         ENTER;
2111
2112         /* remove timeouts*/
2113         for (int i = 0; i < 2; i++) {
2114                 if (gtimeo_id[i] != 0)
2115                         g_source_remove(gtimeo_id[i]);
2116         }
2117
2118         /* set all data-handle free */
2119         if (bm_data_handle != NULL) {
2120                 _DBG("setting handle free - deinitializing");
2121                 bm_set_free_data_handles(&bm_data_handle);
2122         }
2123
2124         /* set flag handle free*/
2125         BM_FREE(bm_req_flag_h);
2126
2127         EXIT;
2128         return;
2129 }