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