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