/* * Copyright (c) 2019 Samsung Electronics Co., Ltd. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License") * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include #include #include #include #include "bm_power_engine.h" #include "bm_dbg.h" #include "bm_common.h" #include "bm_config_parser.h" #include "bm_plugin_manager.h" #include "bm_server_db.h" #include "bm_private.h" #include "bd_private.h" #include "bm_util.h" #include "bd_history_item.h" bm_feature_data_h bm_data_handle = NULL; GHashTable *gl_hash = NULL; static struct bm_req_feature_data_handle_flag_s *bm_req_flag_h = NULL; const double cmah = 3600; int battery_capacity = 500; int gtimeo_id[2]; static int data_collection_period = 600000; 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) { ENTER; BM_CHECK_INPUT_PARAM(app_id); BM_RETURN_VAL((resource_id < BM_PLUGIN_ID_MAX), {}, BATTERY_MONITOR_ERROR_INVALID_PARAMETER, "invalid resource-id param"); _DBG("usage requested - app-id[%s], resource_id[%d], start_time [%ld] end_time[%ld]", app_id, resource_id, (long int)start_time, (long int)end_time); int error = BATTERY_MONITOR_ERROR_NONE; appid_usage_s *app_usage = bm_server_query_app_usage_by_appid_ci(app_id, start_time, end_time, &error); if (!app_usage) { _ERR("battery usage data for app_id(%s) is not available", app_id); return BATTERY_MONITOR_ERROR_INTERNAL; } if (error != BATTERY_MONITOR_ERROR_NONE) { _ERR("error reported, error = %d", error); return BATTERY_MONITOR_ERROR_INTERNAL; } if (app_usage->AppId == NULL) { _ERR("Battery Usage for AppId not found"); bm_appid_usage_free(app_usage); return BATTERY_MONITOR_ERROR_RECORD_NOT_FOUND; } if (resource_id == BM_PLUGIN_ID_BLE) *battery_usage = bm_calc_individual_mah_consumption(app_usage->rId_ble, cmah); else if (resource_id == BM_PLUGIN_ID_WIFI) *battery_usage = bm_calc_individual_mah_consumption(app_usage->rId_wifi, cmah); else if (resource_id == BM_PLUGIN_ID_CPU) *battery_usage = bm_calc_individual_mah_consumption(app_usage->rId_cpu, cmah); else if (resource_id == BM_PLUGIN_ID_DISPLAY) *battery_usage = bm_calc_individual_mah_consumption(app_usage->rId_display, cmah); else if (resource_id == BM_PLUGIN_ID_DEVICE_NETWORK) *battery_usage = bm_calc_individual_mah_consumption(app_usage->rId_device_network, cmah); #ifdef DISABLE_FEATURE_DATA_FROM_GPS_HRM_PLUGIN else if (resource_id == BM_PLUGIN_ID_GPS_SENSOR) *battery_usage = bm_calc_individual_mah_consumption(app_usage->rId_gps, cmah); else if (resource_id == BM_PLUGIN_ID_HRM_SENSOR) *battery_usage = bm_calc_individual_mah_consumption(app_usage->rId_hrm, cmah); else *battery_usage = -1; #endif /* DISABLE_FEATURE_DATA_FROM_GPS_HRM_PLUGIN */ bm_appid_usage_free(app_usage); EXIT; return BATTERY_MONITOR_ERROR_NONE; } int bm_engine_get_total_mah_usage_by_app_id_ci(const gchar* app_id, gint64 start_time, gint64 end_time, double *battery_usage) { ENTER; BM_CHECK_INPUT_PARAM(app_id); _DBG("usage requested - app-id[%s], start_time [%ld] end_time[%ld]", app_id, (long int)start_time, (long int)end_time); int error = BATTERY_MONITOR_ERROR_NONE; appid_usage_s *app_usage = bm_server_query_app_usage_by_appid_ci(app_id, start_time, end_time, &error); if (!app_usage) { _ERR("battery usage data for app_id(%s) is not available", app_id); return BATTERY_MONITOR_ERROR_INTERNAL; } if (error != BATTERY_MONITOR_ERROR_NONE) { _ERR("error reported, error = %d", error); return BATTERY_MONITOR_ERROR_INTERNAL; } if (app_usage->AppId == NULL) { _ERR("Battery Usage for AppId not found"); bm_appid_usage_free(app_usage); return BATTERY_MONITOR_ERROR_RECORD_NOT_FOUND; } int total_consumption = (app_usage->rId_ble + app_usage->rId_wifi + app_usage->rId_cpu + \ app_usage->rId_display + app_usage->rId_device_network); #ifdef DISABLE_FEATURE_DATA_FROM_GPS_HRM_PLUGIN total_consumption += (app_usage->rId_gps + app_usage->rId_hrm); #endif /* DISABLE_FEATURE_DATA_FROM_GPS_HRM_PLUGIN */ *battery_usage = bm_calc_individual_mah_consumption(total_consumption, cmah); _INFO("total battery consumption is [%lf] for app-id[%s]", *battery_usage, app_id); bm_appid_usage_free(app_usage); EXIT; return BATTERY_MONITOR_ERROR_NONE; } int bm_engine_get_total_mah_usage_by_resource_id_ci(gint resource_id, gint64 start_time, gint64 end_time, double *battery_usage) { ENTER; BM_RETURN_VAL((resource_id < BM_PLUGIN_ID_MAX), {}, BATTERY_MONITOR_ERROR_INVALID_PARAMETER, "invalid resource-id"); _DBG("usage requested - resource_id[%d], start_time [%ld] end_time[%ld]", resource_id, (long int)start_time, (long int)end_time); int error = BATTERY_MONITOR_ERROR_NONE; const char *resource_id_str = NULL; resource_id_str = bm_get_resource_id_string(resource_id); if (g_strcmp0(resource_id_str, "UNKNOWN RESOURCE-ID") == 0) { _ERR("invalid resource-id"); return BATTERY_MONITOR_ERROR_INTERNAL; } _INFO("resource string - [%s]", resource_id_str); resourceid_usage_s *resource_usage = bm_server_query_resource_usage_resourceid_ci(resource_id_str, start_time, end_time, &error); if (!resource_usage) { _ERR("battery usage data for resource-id(%s) is not available", resource_id_str); return BATTERY_MONITOR_ERROR_INTERNAL; } if (error != BATTERY_MONITOR_ERROR_NONE) { _ERR("error reported, error = %d", error); return BATTERY_MONITOR_ERROR_INTERNAL; } *battery_usage = bm_calc_individual_mah_consumption(resource_usage->usage, cmah); bm_resourceid_usage_free(resource_usage); EXIT; return BATTERY_MONITOR_ERROR_NONE; } 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) { ENTER; BM_CHECK_INPUT_PARAM(app_id); BM_CHECK_INPUT_PARAM(battery_data); _DBG("usage requested - app-id[%s], start_time[%ld] end_time[%ld]", \ app_id, (long int)start_time, (long int)end_time); int error = BATTERY_MONITOR_ERROR_NONE; appid_usage_s *app_usage = bm_server_query_app_usage_by_appid_ci(app_id, start_time, end_time, &error); if (!app_usage) { _ERR("battery usage data for app_id(%s) is not available", app_id); return BATTERY_MONITOR_ERROR_INTERNAL; } if (error != BATTERY_MONITOR_ERROR_NONE) { _ERR("error reported, error = %d", error); return BATTERY_MONITOR_ERROR_INTERNAL; } if (app_usage->AppId == NULL) { _ERR("Battery Usage for AppId not found"); bm_appid_usage_free(app_usage); return BATTERY_MONITOR_ERROR_RECORD_NOT_FOUND; } battery_data->ble_val = app_usage->rId_ble; battery_data->wifi_val = app_usage->rId_wifi; battery_data->cpu_val = app_usage->rId_cpu; battery_data->dp_val = app_usage->rId_display; battery_data->dn_val = app_usage->rId_device_network; #ifdef DISABLE_FEATURE_DATA_FROM_GPS_HRM_PLUGIN battery_data->gps_val = app_usage->rId_gps; battery_data->hrm_val = app_usage->rId_hrm; battery_data->bat_val = app_usage->rId_battery; #endif /* DISABLE_FEATURE_DATA_FROM_GPS_HRM_PLUGIN */ bm_appid_usage_free(app_usage); EXIT; return BATTERY_MONITOR_ERROR_NONE; } void bm_engine_set_req_flag_handle(bm_plugin_id_e req_plugin_id, bool value) { ENTER; if (!bm_req_flag_h) { _ERR("invalid flag handle"); return; } switch (req_plugin_id) { case BM_PLUGIN_ID_BLE: bm_req_flag_h->req_ble_data = value; break; case BM_PLUGIN_ID_WIFI: bm_req_flag_h->req_wifi_data = value; break; case BM_PLUGIN_ID_CPU: bm_req_flag_h->req_cpu_data = value; break; case BM_PLUGIN_ID_DISPLAY: bm_req_flag_h->req_dp_data = value; break; case BM_PLUGIN_ID_DEVICE_NETWORK: bm_req_flag_h->req_dn_data = value; break; #ifdef DISABLE_FEATURE_DATA_FROM_GPS_HRM_PLUGIN case BM_PLUGIN_ID_GPS_SENSOR: bm_req_flag_h->req_gps_data = value; break; case BM_PLUGIN_ID_HRM_SENSOR: bm_req_flag_h->req_hrm_data = value; break; #endif /* DISABLE_FEATURE_DATA_FROM_GPS_HRM_PLUGIN */ default: _DBG("Invalid plugin ID"); break; } EXIT; return; } void bm_set_req_flag_handles(bool value) { ENTER; if (!bm_req_flag_h) { _ERR("invalid flag handle"); return; } bm_req_flag_h->req_ble_data = value; bm_req_flag_h->req_wifi_data = value; bm_req_flag_h->req_cpu_data = value; bm_req_flag_h->req_dp_data = value; bm_req_flag_h->req_dn_data = value; #ifdef DISABLE_FEATURE_DATA_FROM_GPS_HRM_PLUGIN bm_req_flag_h->req_gps_data = value; bm_req_flag_h->req_hrm_data = value; #endif /* DISABLE_FEATURE_DATA_FROM_GPS_HRM_PLUGIN */ _INFO("request flags set-[%s]", (value == true) ? "TRUE" : "FALSE"); EXIT; return; } static int bm_appid_session_usage_map(char *app_id, int app_usage, bm_plugin_id_e resource_id) { ENTER; BM_CHECK_INPUT_PARAM(app_id); void *prv_data = NULL; void *prv_app_id = NULL; int ret_val = BATTERY_MONITOR_ERROR_NONE; _DBG("app_id [%s] app_usage is [%d]", app_id, app_usage); if (g_hash_table_lookup_extended(gl_hash, app_id, &prv_app_id, &prv_data) == true) { appid_usage_s *temp = (appid_usage_s *)prv_data; if (resource_id == BM_PLUGIN_ID_BLE) temp->rId_ble += app_usage; else if (resource_id == BM_PLUGIN_ID_WIFI) temp->rId_wifi += app_usage; else if (resource_id == BM_PLUGIN_ID_CPU) temp->rId_cpu += app_usage; else if (resource_id == BM_PLUGIN_ID_DISPLAY) temp->rId_display += app_usage; else if (resource_id == BM_PLUGIN_ID_DEVICE_NETWORK) temp->rId_device_network += app_usage; #ifdef DISABLE_FEATURE_DATA_FROM_GPS_HRM_PLUGIN else if (resource_id == BM_PLUGIN_ID_GPS_SENSOR) temp->rId_gps += app_usage; else if (resource_id == BM_PLUGIN_ID_HRM_SENSOR) temp->rId_hrm += app_usage; #endif /* DISABLE_FEATURE_DATA_FROM_GPS_HRM_PLUGIN */ _DBG("update - app_usage for app_id(%s), for resource(%d), by usage(%d)", app_id, resource_id, app_usage); //_DBG("session usage bt %d, wifi %d, cpu %d, dsp %d, dn %d", temp->rId_ble, temp->rId_wifi, temp->rId_cpu, //temp->rId_display, temp->rId_device_network); } else { appid_usage_s *temp = (appid_usage_s *)calloc(1, sizeof(appid_usage_s)); if (temp == NULL) { _ERR("memory allocation failed"); return BATTERY_MONITOR_ERROR_OUT_OF_MEMORY; } if (resource_id == BM_PLUGIN_ID_BLE) temp->rId_ble = app_usage; else if (resource_id == BM_PLUGIN_ID_WIFI) temp->rId_wifi = app_usage; else if (resource_id == BM_PLUGIN_ID_CPU) temp->rId_cpu = app_usage; else if (resource_id == BM_PLUGIN_ID_DISPLAY) temp->rId_display = app_usage; else if (resource_id == BM_PLUGIN_ID_DEVICE_NETWORK) temp->rId_device_network = app_usage; #ifdef DISABLE_FEATURE_DATA_FROM_GPS_HRM_PLUGIN else if (resource_id == BM_PLUGIN_ID_GPS_SENSOR) temp->rId_gps = app_usage; else if (resource_id == BM_PLUGIN_ID_HRM_SENSOR) temp->rId_hrm = app_usage; #endif /* DISABLE_FEATURE_DATA_FROM_GPS_HRM_PLUGIN */ _DBG("insert - app_usage app_id(%s), for resource(%d), by usage(%d)", app_id, resource_id, app_usage); _INFO("inserted - %d", g_hash_table_insert(gl_hash, g_strdup(app_id), temp)); } EXIT; return ret_val; } static int bm_insert_appid_session_usage_to_db() { ENTER; GHashTableIter iter; gpointer key, value; appid_usage_s *app_usage = NULL; int ret_val = BATTERY_MONITOR_ERROR_NONE; long int ret_time = bm_get_log_time(data_collection_period); g_hash_table_iter_init(&iter, gl_hash); while (g_hash_table_iter_next(&iter, &key, &value)) { app_usage = (appid_usage_s *)value; app_usage->AppId = (char *)key; app_usage->log_time = ret_time; _DBG("Calculated Power for Appid(%s) for resources bt(%d), wifi(%d), cpu(%d), \ display(%d), dn(%d)", app_usage->AppId, app_usage->rId_ble, app_usage->rId_wifi, app_usage->rId_cpu, app_usage->rId_display, app_usage->rId_device_network); ret_val = bm_server_appid_insert_to_db(app_usage->AppId); if (ret_val != BATTERY_MONITOR_ERROR_NONE) _ERR("Insert of Appid failed "); else _DBG("Insert successful"); ret_val = bm_server_app_usage_insert_to_db(app_usage); if (ret_val != BATTERY_MONITOR_ERROR_NONE) _ERR("Insert of App Usage failed "); else _DBG("Insert successful"); } EXIT; return ret_val; } /* TODO: Add Normalization of values based on sP_Power_xxx & Time unit */ int bm_ble_calc_power_and_commit(bm_bluetooth_st *handle, bool mode) { ENTER; BM_CHECK_INPUT_PARAM(handle); GSList *bt_data_iterator = NULL; GSList *bt_atm_iterator = NULL; void *prv_data = NULL; void *prv_app_id = NULL; int ret_val = BATTERY_MONITOR_ERROR_NONE; /* creating hash-map with (key, value) = (app-id, data) */ GHashTable *hash = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, NULL); long int edTime = 0, stTime = 0; long int sesTime = 0, conTime = 0, RX_app = 0, TX_app = 0; long int RX_system = 0, TX_system = 0, tx_time = 0, rx_time = 0; long int scTime = 0; double onTime = 0; /* iterating over list for data accumulation */ for (bt_data_iterator = handle->bt_data_list; bt_data_iterator; bt_data_iterator = bt_data_iterator->next) { bm_bluetooth_st *datalistnode = (bm_bluetooth_st *)(bt_data_iterator->data); edTime = datalistnode->stopTime; stTime = datalistnode->startTime; // scTime += datalistnode->scanTime; conTime += datalistnode->connectedTime; rx_time += datalistnode->rxTime; tx_time += datalistnode->txTime; sesTime += (edTime-stTime); bt_atm_iterator = datalistnode->atm_list; for ( ; bt_atm_iterator; bt_atm_iterator = bt_atm_iterator->next) { app_time_map_st2 *bt_atm_node = NULL; bt_atm_node = bt_atm_iterator->data; if (!bt_atm_node) { _DBG("no data available"); continue; } _DBG("bt data available"); /* Get the system usage */ if (g_strcmp0(bt_atm_node->app_id, BM_APPID_SYSTEM) == 0) { _DBG("ignore - app_id(%s), time(%d), rx(%d), tx(%d)", bt_atm_node->app_id, bt_atm_node->time, bt_atm_node->rx, bt_atm_node->tx); RX_system += bt_atm_node->rx; TX_system += bt_atm_node->tx; continue; } RX_app += bt_atm_node->rx; TX_app += bt_atm_node->tx; onTime += bt_atm_node->time; prv_data = NULL; prv_app_id = NULL; if (g_hash_table_lookup_extended(hash, bt_atm_node->app_id, &prv_app_id, &prv_data) == true) { _DBG("previous app_id = %s", (char *)prv_app_id); app_time_map_st2 *temp = (app_time_map_st2 *)prv_data; bt_atm_node->time += temp->time; bt_atm_node->rx += temp->rx; bt_atm_node->tx += temp->tx; _DBG("update - app_id(%s), time(%d), rx(%d), tx(%d)", bt_atm_node->app_id, bt_atm_node->time, bt_atm_node->rx, bt_atm_node->tx); _INFO("updated - %d", g_hash_table_replace(hash, bt_atm_node->app_id, bt_atm_node)); } else { _DBG("insert - app_id(%s), time(%d), rx(%d), tx(%d)", bt_atm_node->app_id, bt_atm_node->time, bt_atm_node->rx, bt_atm_node->tx); _INFO("inserted - %d", g_hash_table_insert(hash, bt_atm_node->app_id, bt_atm_node)); } } } // startTime and stopTime use seconds. So, we don't have to convert sesTime conTime /= 1000; rx_time /= 1000; tx_time /= 1000; /* Read standard Rated Values from Device Spec File/Power Profile File */ 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; 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); if (ret_val != BATTERY_MONITOR_ERROR_NONE) _ERR("failed to get bt power params"); _DBG("received bt power params - idle[%lf], scan[%lf], connected[%lf], rx[%lf], tx[%lf]", sP_power_bt_idle, sP_power_bt_scan, sP_power_bt_conn, sP_power_bt_tx, sP_power_bt_rx); /* BT power consumption Level - 1 at the Resource Level */ long int P_power_bt = 0, P_power_data = 0, P_power_conn = 0; /* Remove transmit time from connected time */ long int rconTime = conTime - (rx_time + tx_time); P_power_conn = ((sP_power_bt_idle) * (sesTime - conTime)) + ((sP_power_bt_conn) * (rconTime)); /* Amount based usage calculation */ // P_power_data = ((sP_power_bt_tx) * TX_app) + ((sP_power_bt_rx) * RX_app); /* Use rx and tx time to calculate the usage */ P_power_data = ((sP_power_bt_tx) * tx_time + (sP_power_bt_rx) * rx_time); P_power_bt = P_power_conn + P_power_data; _DBG("Calculated Power for Bluetooth P_power_bt(%ld), P_power_conn (%ld), P_power_data(%ld)", P_power_bt, P_power_conn, P_power_data); /* BT power consumption Level - 2 at the Application Level */ GHashTableIter iter1; gpointer key, value; g_hash_table_iter_init(&iter1, hash); long int rx_tx_time = tx_time + rx_time; long int left_rx_tx_time = rx_tx_time; double apptime = 0, csc_t = 0; //Normalize if (onTime != 0 && onTime > rx_tx_time) { _DBG("Normalize the scan app scan time"); csc_t = (double)rx_tx_time/onTime; while (g_hash_table_iter_next(&iter1, &key, &value)) { app_time_map_st2 *temp = (app_time_map_st2 *)value; apptime = temp->time; if (temp->time > 0) { temp->time = (apptime * csc_t); left_rx_tx_time -= temp->time; } } } else left_rx_tx_time -= onTime; long int P_power_app_bt = 0, P_power_app_data = 0, P_power_app_conn = 0; char *appid = NULL; long int apprx = 0, apptx = 0; long int ret_time = bm_get_log_time(data_collection_period); long int total_app_pw = 0, base_res_pw = 0; /* Coefficient to divide the rx and tx time wrt rx and tx bytes */ double crtx_t = 0; if ((left_rx_tx_time > 0) && (RX_app != 0 || TX_app != 0)) crtx_t = (double)left_rx_tx_time/(TX_app + RX_app + RX_system + TX_system); appid_usage_s app_usage; GHashTableIter iter; g_hash_table_iter_init(&iter, hash); while (g_hash_table_iter_next(&iter, &key, &value)) { P_power_app_bt = 0, P_power_app_data = 0, P_power_app_conn = 0; apprx = 0, apptx = 0, apptime = 0; app_time_map_st2 *temp = (app_time_map_st2 *)value; appid = temp->app_id; apprx = temp->rx; apptx = temp->tx; apptime = temp->time; // P_power_app_data = (sP_power_bt_tx * (crx_t * apptx)) + (sP_power_bt_rx * (ctx_t * apprx)); // if (onTime != 0) // P_power_app_conn = (P_power_conn * apptime)/onTime; //check for 0 denominator & same units // P_power_app_bt = P_power_app_data + P_power_app_conn; int app_transmit = apprx + apptx; P_power_app_bt = sP_power_bt_rx * ((crtx_t * app_transmit) + apptime); app_usage.AppId = appid; app_usage.rId_ble = P_power_app_bt; app_usage.log_time = ret_time; total_app_pw += P_power_app_bt; /* Call Insert Function */ _DBG("Calculated Power for Appid(%s) - P_power_app_bt(%ld), P_power_app_conn(%ld), P_power_app_data(%ld)", appid, P_power_app_bt, P_power_app_conn, P_power_app_data); if (mode) { ret_val = bm_server_appid_insert_to_db(app_usage.AppId); if (ret_val != BATTERY_MONITOR_ERROR_NONE) _ERR("Insert of BT appid failed "); ret_val = bm_server_app_usage_insert_to_db(&app_usage); } else/* Call Global Hash */ ret_val = bm_appid_session_usage_map(app_usage.AppId, app_usage.rId_ble, BM_PLUGIN_ID_BLE); if (ret_val != BATTERY_MONITOR_ERROR_NONE) _ERR("Insert of BT App failed "); } /* commit to database the output after power calculation */ resourceid_usage_s res_usage; res_usage.ResourceId = BM_RID_BLE; res_usage.log_time = ret_time; res_usage.usage = P_power_bt; ret_val = bm_server_resource_usage_insert_to_db(&res_usage); if (ret_val != BATTERY_MONITOR_ERROR_NONE) _ERR("Insert of BT resource failed "); if (P_power_bt > total_app_pw) { base_res_pw = (P_power_bt - total_app_pw); res_usage.usage = base_res_pw; ret_val = bm_server_resource_base_usage_insert_to_db(&res_usage); if (ret_val != BATTERY_MONITOR_ERROR_NONE) _ERR("Insert of BT base resource failed "); } bd_gl_ble_stat_s *gble_st = (bd_gl_ble_stat_s *)calloc(1, sizeof(bd_gl_ble_stat_s)); if (gble_st == NULL) { _ERR("memory allocation failed"); return BATTERY_MONITOR_ERROR_OUT_OF_MEMORY; } gble_st->time_s = ret_time; gble_st->ble_idle_time = (sesTime - (scTime + conTime)); gble_st->ble_rx_time = rx_time; gble_st->ble_tx_time = tx_time; gble_st->ble_pwi_val = P_power_bt; ret_val = bm_server_battery_dump_insert_to_db(gble_st, 0); if (ret_val != BATTERY_MONITOR_ERROR_NONE) _ERR("Insert of GBLE failed "); BM_FREE(gble_st); bd_gl_bst_stat_s *gbst_st = (bd_gl_bst_stat_s *)calloc(1, sizeof(bd_gl_bst_stat_s)); if (gbst_st == NULL) { _ERR("memory allocation failed"); return BATTERY_MONITOR_ERROR_OUT_OF_MEMORY; } gbst_st->time_s = ret_time; gbst_st->off_time = data_collection_period / 1000; gbst_st->off_time -= sesTime; gbst_st->low_time = 0/*(sesTime - (scTime + conTime))*/; gbst_st->med_time = 0/*scTime*/; gbst_st->high_time = 0/*conTime*/; ret_val = bm_server_battery_dump_insert_to_db(gbst_st, 6); if (ret_val != BATTERY_MONITOR_ERROR_NONE) _ERR("Insert of GBLE failed "); BM_FREE(gbst_st); /* Free the hash map */ g_hash_table_destroy(hash); /* Dump resource usage */ _DBG("BLE usage : %ld bytes", RX_system + TX_system + RX_app + TX_app); if (RX_system > 0 || TX_system > 0 || RX_app > 0 || TX_app > 0) { history_item_s hi; bd_print_history_item_reset(&hi); hi.cmd_s = CM_USAGE; hi.usage_type = USAGE_BLUETOOTH; hi.usage = (RX_system + TX_system + RX_app + TX_app) / ((double)data_collection_period / 60000); // bytes / minute bd_store_history_item(&hi); } EXIT; return ret_val; } int bm_wifi_calc_power_and_commit(bm_wifi_st *handle, bool mode) { ENTER; BM_CHECK_INPUT_PARAM(handle); GSList *wifi_data_iterator = NULL; GSList *wifi_atm_iterator = NULL; void *prv_data = NULL; void *prv_app_id = NULL; int ret_val = BATTERY_MONITOR_ERROR_NONE; /* creating hash-map with (key, value) = (app-id, data) */ GHashTable *hash = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, NULL); long int edTime = 0, stTime = 0; long int sesTime = 0, scTime = 0, tl_total = 0; long int tl0 = 0, tl1 = 0, tl2 = 0, tl3 = 0, tl4 = 0; double onTime = 0; long int RX = 0, TX = 0, rx_time = 0, tx_time = 0; /* iterating over list for data accumulation */ for (wifi_data_iterator = handle->wifi_data_list; wifi_data_iterator; wifi_data_iterator = wifi_data_iterator->next) { bm_wifi_st *datalistnode = (bm_wifi_st *)(wifi_data_iterator->data); edTime = datalistnode->endTime; stTime = datalistnode->startTime; sesTime += (edTime - stTime); scTime += datalistnode->scanTime; tl0 += datalistnode->time_level_0; tl1 += datalistnode->time_level_1; tl2 += datalistnode->time_level_2; tl3 += datalistnode->time_level_3; tl4 += datalistnode->time_level_4; rx_time += datalistnode->rxTime; tx_time += datalistnode->txTime; wifi_atm_iterator = datalistnode->atm_list; for ( ; wifi_atm_iterator; wifi_atm_iterator = wifi_atm_iterator->next) { app_time_map_st2 *wifi_atm_node = NULL; wifi_atm_node = wifi_atm_iterator->data; if (!wifi_atm_node) { _DBG("no data available"); continue; } _DBG("wifi data available"); RX += wifi_atm_node->rx; TX += wifi_atm_node->tx; onTime += wifi_atm_node->time; prv_app_id = NULL; prv_data = NULL; if (g_hash_table_lookup_extended(hash, wifi_atm_node->app_id, &prv_app_id, &prv_data) == true) { _DBG("previous app_id = %s", (char *)prv_app_id); app_time_map_st2 *temp = (app_time_map_st2 *)prv_data; wifi_atm_node->time += temp->time; wifi_atm_node->rx += temp->rx; wifi_atm_node->tx += temp->tx; _DBG("update - app_id(%s), time(%d), rx(%d), tx(%d)", wifi_atm_node->app_id, wifi_atm_node->time, wifi_atm_node->rx, wifi_atm_node->tx); _INFO("updated - %d", g_hash_table_replace(hash, wifi_atm_node->app_id, wifi_atm_node)); } else { _DBG("insert - app_id(%s), time(%d), rx(%d), tx(%d)", wifi_atm_node->app_id, wifi_atm_node->time, wifi_atm_node->rx, wifi_atm_node->tx); _INFO("inserted - %d", g_hash_table_insert(hash, wifi_atm_node->app_id, wifi_atm_node)); } } } /* Read standard Rated Values from Device Spec File/Power Profile File */ 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; double sP_power_wf_tl3 = 0, sP_power_wf_tl4 = 0, sP_power_wf_tx = 0, sP_power_wf_rx = 0; ret_val = bm_get_wifi_power_params(&sP_power_wf_tl0, &sP_power_wf_tl1, &sP_power_wf_tl2, &sP_power_wf_tl3, &sP_power_wf_tl4, &sP_power_wf_scan, &sP_power_wf_idle, &sP_power_wf_rx, &sP_power_wf_tx); if (ret_val != BATTERY_MONITOR_ERROR_NONE) _ERR("failed to get wifi power params"); _DBG("received wifi power params - rssi_0[%lf], rssi_1[%lf], rssi_2[%lf], rssi_3[%lf], rssi_4[%lf], scan[%lf], \ idle[%lf], rx[%lf], tx[%lf]", sP_power_wf_tl0, sP_power_wf_tl1, sP_power_wf_tl2, sP_power_wf_tl3, sP_power_wf_tl4, sP_power_wf_scan, sP_power_wf_idle, sP_power_wf_rx, sP_power_wf_tx); tl0 /= 1000; tl1 /= 1000; tl2 /= 1000; tl3 /= 1000; tl4 /= 1000; onTime /= 1000; rx_time /= 1000; tx_time /= 1000; tl_total = tl0 + tl1 + tl2 + tl3 + tl4; /* Wifi power consumption Level - 1 at the Resource Level */ long int P_power_wifi = 0, P_power_data = 0, P_power_conn = 0; P_power_conn = ((sP_power_wf_tl0 * tl0) + (sP_power_wf_tl1 * tl1) + (sP_power_wf_tl2 * tl2) + (sP_power_wf_tl3 * tl3) + (sP_power_wf_tl4 * tl4) + (sP_power_wf_scan * scTime) + (sP_power_wf_idle * (sesTime - (tl_total + scTime)))); /* Amount based usage calculation */ // P_power_data = ((sP_power_wf_tx) * TX) + ((sP_power_wf_rx) * RX); /* Use rx and tx time to calculate the usage */ P_power_data = ((sP_power_wf_tx * tx_time) + (sP_power_wf_rx * rx_time)); P_power_wifi = P_power_conn + P_power_data; _DBG("Calculated Power for Wifi P_power_wifi(%ld), P_power_conn (%ld), P_power_data(%ld)", P_power_wifi, P_power_conn, P_power_data); /* Wifi power consumption Level - 2 at the Application Level */ GHashTableIter iter; gpointer key, value; g_hash_table_iter_init(&iter, hash); long int P_power_app_wifi = 0, P_power_app_data = 0, P_power_app_conn = 0; char *appid = NULL; long int apprx = 0, apptx = 0; double apptime = 0, crx_t = 0, ctx_t = 0; long int rx_t = 0, tx_t = 0; long int ret_time = bm_get_log_time(data_collection_period); long int total_app_pw = 0, base_res_pw = 0; /* Coefficient to divide the rx and tx time wrt rx and tx bytes */ if (RX != 0) crx_t = (double)rx_time/RX; if (TX != 0) ctx_t = (double)tx_time/TX; appid_usage_s app_usage; while (g_hash_table_iter_next(&iter, &key, &value)) { P_power_app_wifi = 0; P_power_app_data = 0; P_power_app_conn = 0; apprx = 0, apptx = 0, apptime = 0; app_time_map_st2 *temp = (app_time_map_st2 *)value; appid = temp->app_id; apprx = temp->rx; rx_t += apprx; apptx = temp->tx; tx_t += apptx; apptime = temp->time; apptime /= 1000; P_power_app_data = (sP_power_wf_tx * (ctx_t * apptx)) + (sP_power_wf_rx * (crx_t * apprx)); if (onTime != 0) P_power_app_conn = (P_power_conn * apptime)/onTime; //check for 0 denominator & same units P_power_app_wifi = P_power_app_data + P_power_app_conn; app_usage.AppId = appid; app_usage.rId_wifi = P_power_app_wifi; app_usage.log_time = ret_time; total_app_pw += P_power_app_wifi; /* Call Insert Function */ _DBG("Calculated Power for Appid(%s) - P_power_app_wifi(%ld), P_power_app_conn(%ld), P_power_app_data(%ld)", appid, P_power_app_wifi, P_power_app_conn, P_power_app_data); if (mode) { ret_val = bm_server_appid_insert_to_db(app_usage.AppId); if (ret_val != BATTERY_MONITOR_ERROR_NONE) _ERR("Insert of WiFi appid failed "); ret_val = bm_server_app_usage_insert_to_db(&app_usage); } else/* Call Global Hash */ ret_val = bm_appid_session_usage_map(app_usage.AppId, app_usage.rId_wifi, BM_PLUGIN_ID_WIFI); if (ret_val != BATTERY_MONITOR_ERROR_NONE) _ERR("Insert of Wifi App failed "); } /* commit to database the output after power calculation */ resourceid_usage_s res_usage; res_usage.ResourceId = BM_RID_WIFI; res_usage.log_time = ret_time; res_usage.usage = P_power_wifi; ret_val = bm_server_resource_usage_insert_to_db(&res_usage); if (ret_val != BATTERY_MONITOR_ERROR_NONE) _ERR("Insert of Wifi resource failed "); if (P_power_wifi > total_app_pw) { base_res_pw = (P_power_wifi - total_app_pw); res_usage.usage = base_res_pw; ret_val = bm_server_resource_base_usage_insert_to_db(&res_usage); if (ret_val != BATTERY_MONITOR_ERROR_NONE) _ERR("Insert of Wifi base resource failed "); } bd_gl_wifi_stat_s *gwfl_st = (bd_gl_wifi_stat_s *)calloc(1, sizeof(bd_gl_wifi_stat_s)); if (gwfl_st == NULL) { _ERR("memory allocation failed"); return BATTERY_MONITOR_ERROR_OUT_OF_MEMORY; } gwfl_st->time_s = ret_time; gwfl_st->wifi_on_time = sesTime; gwfl_st->wifi_conn_time = tl_total; gwfl_st->wifi_idle_time = (sesTime - (tl_total + scTime)); gwfl_st->wifi_rx_time = rx_time; gwfl_st->wifi_tx_time = tx_time; ret_val = bm_server_battery_dump_insert_to_db(gwfl_st, 1); if (ret_val != BATTERY_MONITOR_ERROR_NONE) _ERR("Insert of GWFL failed "); else _DBG("Insert successful"); BM_FREE(gwfl_st); bd_gl_wst_stat_s *gwst_st = (bd_gl_wst_stat_s *)calloc(1, sizeof(bd_gl_wst_stat_s)); if (gwst_st == NULL) { _ERR("memory allocation failed"); return BATTERY_MONITOR_ERROR_OUT_OF_MEMORY; } gwst_st->time_s = ret_time; gwst_st->wscan_time = scTime; gwst_st->wnone_time = tl0; gwst_st->wpoor_time = tl1; gwst_st->wmed_time = tl2; gwst_st->wgood_time = tl3; gwst_st->wgrt_time = tl4; ret_val = bm_server_battery_dump_insert_to_db(gwst_st, 5); if (ret_val != BATTERY_MONITOR_ERROR_NONE) _ERR("Insert of GWFL failed "); else _DBG("Insert successful"); BM_FREE(gwst_st); /* Free the Hash Map */ g_hash_table_destroy(hash); /* Dump resource usage */ _DBG("Wi-Fi usage : %ld bytes", RX + TX); if (RX > 0 || TX > 0) { history_item_s hi; bd_print_history_item_reset(&hi); hi.cmd_s = CM_USAGE; hi.usage_type = USAGE_WIFI; hi.usage = (RX + TX) / ((double)data_collection_period / 60000); // bytes / minute bd_store_history_item(&hi); } EXIT; return ret_val; } int bm_cpu_calc_power_and_commit(bm_cpu_st *handle, bool mode) { ENTER; BM_CHECK_INPUT_PARAM(handle); GSList *cpu_data_iterator = NULL; GSList *cpu_atm_iterator = NULL; void *prv_data = NULL; void *prv_app_id = NULL; int ret_val = BATTERY_MONITOR_ERROR_NONE; /* creating hash-map with (key, value) = (app-id, data) */ GHashTable *hash = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, NULL); long int uTime = 0, sTime = 0; double onTime = 0; /* iterating over list for data accumulation */ for (cpu_data_iterator = handle->cpu_data_list; cpu_data_iterator; cpu_data_iterator = cpu_data_iterator->next) { bm_cpu_st *datalistnode = (bm_cpu_st *)(cpu_data_iterator->data); uTime += datalistnode->utime; sTime += datalistnode->stime; cpu_atm_iterator = datalistnode->atm_list; for ( ; cpu_atm_iterator; cpu_atm_iterator = cpu_atm_iterator->next) { app_time_map_st1 *cpu_atm_node = (app_time_map_st1 *)cpu_atm_iterator->data; if (!cpu_atm_node) { _DBG("no data available"); continue; } _DBG("cpu data available"); onTime += cpu_atm_node->time; prv_app_id = NULL; prv_data = NULL; if (g_hash_table_lookup_extended(hash, cpu_atm_node->app_id, &prv_app_id, &prv_data) == true) { _DBG("previous app_id = %s", (char *)prv_app_id); app_time_map_st1 *cpu_atm_prv_node = (app_time_map_st1 *)prv_data; cpu_atm_node->time += cpu_atm_prv_node->time; _DBG("update - app_id(%s), time(%d)", cpu_atm_node->app_id, cpu_atm_node->time); _INFO("updated - %d", g_hash_table_replace(hash, cpu_atm_node->app_id, cpu_atm_node)); } else { _DBG("insert - app_id(%s), time(%d)", cpu_atm_node->app_id, cpu_atm_node->time); _INFO("inserted - %d", g_hash_table_insert(hash, cpu_atm_node->app_id, cpu_atm_node)); } } } /* Read standard Rated Values from Device Spec File/Power Profile File */ double sP_power_cpu_user = 0, sP_power_cpu_system = 0; ret_val = bm_get_cpu_power_params(&sP_power_cpu_user, &sP_power_cpu_system); if (ret_val != BATTERY_MONITOR_ERROR_NONE) _ERR("failed to get cpu power params"); _DBG("received cpu power params - user[%lf]\n, system[%lf]\n", sP_power_cpu_user, sP_power_cpu_system); /* CPU power consumption Level - 1 at the Resource Level */ long int P_power_cpu = 0, P_power_user = 0, P_power_system = 0; uTime /= 1000; sTime /= 1000; onTime /= 1000; P_power_user = ((sP_power_cpu_user * uTime)); P_power_system = ((sP_power_cpu_system * sTime)); P_power_cpu = P_power_user + P_power_system; _DBG("Calculated Power for CPU P_power_cpu (%ld), P_power_user (%ld), P_power_system (%ld)", P_power_cpu, P_power_user, P_power_system); /* CPU power consumption Level - 2 at the Application Level */ GHashTableIter iter; gpointer key, value; g_hash_table_iter_init(&iter, hash); long int P_power_app_cpu = 0, P_power_app_use = 0; double apptime = 0; char *appid = NULL; long int ret_time = bm_get_log_time(data_collection_period); long int total_app_pw = 0, base_res_pw = 0; appid_usage_s app_usage; while (g_hash_table_iter_next(&iter, &key, &value)) { P_power_app_cpu = 0; P_power_app_use = 0; apptime = 0; app_time_map_st1 *temp = (app_time_map_st1 *)value; appid = temp->app_id; apptime = (temp->time); apptime /= 1000; if (onTime != 0) P_power_app_use = (P_power_cpu * apptime)/onTime; //check for 0 denominator & same units P_power_app_cpu = P_power_app_use; app_usage.AppId = appid; app_usage.rId_cpu = P_power_app_cpu; app_usage.log_time = ret_time; total_app_pw += P_power_app_cpu; /* Call Insert Function */ _DBG("Calculated Power for Appid (%s) P_power_app_cpu (%ld), P_power_app_use (%ld)", appid, P_power_app_cpu, P_power_app_use); if (mode) { ret_val = bm_server_appid_insert_to_db(app_usage.AppId); if (ret_val != BATTERY_MONITOR_ERROR_NONE) _ERR("Insert of CPU appid failed "); ret_val = bm_server_app_usage_insert_to_db(&app_usage); } else ret_val = bm_appid_session_usage_map(app_usage.AppId, app_usage.rId_cpu, BM_PLUGIN_ID_CPU); /* Error Check */ if (ret_val != BATTERY_MONITOR_ERROR_NONE) _ERR("Insert of CPU App failed "); } resourceid_usage_s res_usage; res_usage.ResourceId = BM_RID_CPU; res_usage.log_time = ret_time; res_usage.usage = P_power_cpu; ret_val = bm_server_resource_usage_insert_to_db(&res_usage); if (ret_val != BATTERY_MONITOR_ERROR_NONE) _ERR("Insert of CPU resource failed "); if (P_power_cpu > total_app_pw) { base_res_pw = (P_power_cpu - total_app_pw); res_usage.usage = base_res_pw; ret_val = bm_server_resource_base_usage_insert_to_db(&res_usage); if (ret_val != BATTERY_MONITOR_ERROR_NONE) _ERR("Insert of CPU base resource failed "); } bd_gl_cpu_stat_s *gcpu_st = (bd_gl_cpu_stat_s *)calloc(1, sizeof(bd_gl_cpu_stat_s)); if (gcpu_st == NULL) { _ERR("memory allocation failed"); return BATTERY_MONITOR_ERROR_OUT_OF_MEMORY; } gcpu_st->time_s = ret_time; gcpu_st->usr_time = uTime; gcpu_st->sys_time = sTime; ret_val = bm_server_battery_dump_insert_to_db(gcpu_st, 7); if (ret_val != BATTERY_MONITOR_ERROR_NONE) _ERR("Insert GCPU failed"); BM_FREE(gcpu_st); /* Free the Hash Map */ g_hash_table_destroy(hash); EXIT; return ret_val; } int bm_display_calc_power_and_commit(bm_display_st *handle, bool mode) { ENTER; BM_CHECK_INPUT_PARAM(handle); GSList *dp_data_iterator = NULL; GSList *dp_atm_iterator = NULL; void *prv_data = NULL; void *prv_app_id = NULL; int ret_val = BATTERY_MONITOR_ERROR_NONE; /* creating hash-map with (key, value) = (app-id, data) */ GHashTable *hash = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, NULL); long int edTime = 0, stTime = 0, sesTime = 0; long int highTime = 0, medTime = 0, lowTime = 0; double onTime = 0; /* iterating over list for data accumulation */ for (dp_data_iterator = handle->display_list; dp_data_iterator; dp_data_iterator = dp_data_iterator->next) { bm_display_st *datalistnode = (bm_display_st *)(dp_data_iterator->data); edTime = datalistnode->stop; stTime = datalistnode->start; highTime += datalistnode->high; medTime += datalistnode->med; lowTime += datalistnode->low; sesTime += edTime - stTime; dp_atm_iterator = datalistnode->atm_list; for ( ; dp_atm_iterator; dp_atm_iterator = dp_atm_iterator->next) { app_time_map_st1 *dp_atm_node = (app_time_map_st1 *)dp_atm_iterator->data; if (!dp_atm_node) { _DBG("no data available"); continue; } _DBG("display data available"); onTime += dp_atm_node->time; prv_data = NULL; prv_app_id = NULL; if (g_hash_table_lookup_extended(hash, dp_atm_node->app_id, &prv_app_id, &prv_data) == true) { _DBG("previous app_id = %s", (char *)prv_app_id); app_time_map_st1 *dp_atm_prv_node = (app_time_map_st1 *)prv_data; dp_atm_node->time += dp_atm_prv_node->time; _DBG("update - app_id(%s), time(%d)", dp_atm_node->app_id, dp_atm_node->time); _INFO("updated - %d", g_hash_table_replace(hash, dp_atm_node->app_id, dp_atm_node)); } else { _DBG("insert - app_id(%s), time(%d)", dp_atm_node->app_id, dp_atm_node->time); _INFO("inserted - %d", g_hash_table_insert(hash, dp_atm_node->app_id, dp_atm_node)); } } } /* Read standard Rated Values from Device Spec File/Power Profile File */ double sP_power_dp_low = 0, sP_power_dp_med = 0, sP_power_dp_high = 0; ret_val = bm_get_display_power_params(&sP_power_dp_high, &sP_power_dp_med, &sP_power_dp_low); if (ret_val != BATTERY_MONITOR_ERROR_NONE) _ERR("failed to get cpu power params"); _DBG("received display power params - high[%lf], medium[%lf], low[%lf]", sP_power_dp_high, sP_power_dp_med, sP_power_dp_low); /* Display power consumption Level - 1 at the Resource Level */ lowTime /= 1000; medTime /= 1000; highTime /= 1000; onTime /= 1000; long int P_power_disp = 0, P_power_on = 0; P_power_on = ((sP_power_dp_low * lowTime) + (sP_power_dp_med * medTime) + (sP_power_dp_high * highTime)); P_power_disp = P_power_on; _DBG("Calculated Power for Display P_power_disp (%ld), P_power_on (%ld)", P_power_disp, P_power_on); /* Display power consumption Level - 2 at the Application Level */ GHashTableIter iter; gpointer key, value; g_hash_table_iter_init(&iter, hash); long int P_power_app_disp = 0, P_power_app_on = 0; char *appid = NULL; double apptime = 0; long int ret_time = bm_get_log_time(data_collection_period); long int total_app_pw = 0, base_res_pw = 0; appid_usage_s app_usage; while (g_hash_table_iter_next(&iter, &key, &value)) { P_power_app_disp = 0; P_power_app_on = 0; apptime = 0; app_time_map_st1 *temp = (app_time_map_st1 *)value; appid = temp->app_id; apptime = temp->time; apptime /= 1000; if (onTime != 0) P_power_app_on = (P_power_on * apptime)/onTime; //check for 0 denominator & same units P_power_app_disp = P_power_app_on; app_usage.AppId = appid; app_usage.rId_display = P_power_app_disp; app_usage.log_time = ret_time; total_app_pw += P_power_app_disp; /* Call Insert Function */ _DBG("Calculated Power for Appid (%s) P_power_app_disp(%ld), P_power_app_on (%ld)", appid, P_power_app_disp, P_power_app_on); if (mode) { ret_val = bm_server_appid_insert_to_db(app_usage.AppId); if (ret_val != BATTERY_MONITOR_ERROR_NONE) _ERR("Insert of DSP appid failed "); ret_val = bm_server_app_usage_insert_to_db(&app_usage); } else ret_val = bm_appid_session_usage_map(app_usage.AppId, app_usage.rId_display, BM_PLUGIN_ID_DISPLAY); /* Error Check */ if (ret_val != BATTERY_MONITOR_ERROR_NONE) _ERR("Insert of Display App failed "); } /* commit to database the output after power calculation */ resourceid_usage_s res_usage; res_usage.ResourceId = BM_RID_DISP; res_usage.log_time = ret_time; res_usage.usage = P_power_disp; ret_val = bm_server_resource_usage_insert_to_db(&res_usage); if (ret_val != BATTERY_MONITOR_ERROR_NONE) _ERR("Insert of Display resource failed "); if (P_power_disp > total_app_pw) { base_res_pw = (P_power_disp - total_app_pw); res_usage.usage = base_res_pw; ret_val = bm_server_resource_base_usage_insert_to_db(&res_usage); if (ret_val != BATTERY_MONITOR_ERROR_NONE) _ERR("Insert of Display base resource failed "); } bd_gl_sbr_stat_s *gbr_st = (bd_gl_sbr_stat_s *)calloc(1, sizeof(bd_gl_sbr_stat_s)); if (gbr_st == NULL) { _ERR("memory allocation failed"); return BATTERY_MONITOR_ERROR_OUT_OF_MEMORY; } gbr_st->time_s = ret_time; gbr_st->dark = (data_collection_period / 1000); gbr_st->dark -= sesTime; gbr_st->dim = lowTime; gbr_st->medium = medTime; gbr_st->bright = highTime; ret_val = bm_server_battery_dump_insert_to_db(gbr_st, 3); if (ret_val != BATTERY_MONITOR_ERROR_NONE) _ERR("Insert of GBR failed "); else _DBG("Insert GBR successful"); BM_FREE(gbr_st); /* Free the Hash Map */ g_hash_table_destroy(hash); EXIT; return ret_val; } int bm_device_network_calc_power_and_commit(bm_device_network_st *handle, bool mode) { ENTER; BM_CHECK_INPUT_PARAM(handle); GSList *dn_data_iterator = NULL; GSList *dn_atm_iterator = NULL; void *prv_data = NULL; void *prv_app_id = NULL; int ret_val = BATTERY_MONITOR_ERROR_NONE; /* creating hash-map with (key, value) = (app-id, data) */ GHashTable *hash = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, NULL); long int tl0 = 0, tl1 = 0, tl2 = 0, tl3 = 0, tl4 = 0, tl5 = 0, tl6 = 0; long int RX = 0, TX = 0; double tl_total = 0; /* iterating over list for data accumulation */ for (dn_data_iterator = handle->dn_data_list; dn_data_iterator; dn_data_iterator = dn_data_iterator->next) { bm_device_network_st *datalistnode = (bm_device_network_st *)(dn_data_iterator->data); tl0 += datalistnode->time_level_0; tl1 += datalistnode->time_level_1; tl2 += datalistnode->time_level_2; tl3 += datalistnode->time_level_3; tl4 += datalistnode->time_level_4; tl5 += datalistnode->time_level_5; tl6 += datalistnode->time_level_6; dn_atm_iterator = datalistnode->atm_list; for ( ; dn_atm_iterator; dn_atm_iterator = dn_atm_iterator->next) { app_time_map_st2 *dn_atm_node = (app_time_map_st2 *)dn_atm_iterator->data; if (!dn_atm_node) { _DBG("no data available"); continue; } _DBG("device-network data available"); RX += dn_atm_node->rx; TX += dn_atm_node->tx; prv_data = NULL; prv_app_id = NULL; if (g_hash_table_lookup_extended(hash, dn_atm_node->app_id, &prv_app_id, &prv_data) == true) { _DBG("previous app_id = %s", (char *)prv_app_id); app_time_map_st2 *dn_atm_prv_node = (app_time_map_st2 *)prv_data; dn_atm_node->time += dn_atm_prv_node->time; dn_atm_node->rx += dn_atm_prv_node->rx; dn_atm_node->tx += dn_atm_prv_node->tx; _DBG("update - app_id(%s), time(%d), rx(%d), tx(%d)", dn_atm_node->app_id, dn_atm_node->time, dn_atm_node->rx, dn_atm_node->tx); _INFO("updated - %d", g_hash_table_replace(hash, dn_atm_node->app_id, dn_atm_node)); } else { _DBG("insert - app_id(%s), time(%d), rx(%d), tx(%d)", dn_atm_node->app_id, dn_atm_node->time, dn_atm_node->rx, dn_atm_node->tx); _INFO("inserted - %d", g_hash_table_insert(hash, dn_atm_node->app_id, dn_atm_node)); } } } /* Read standard Rated Values from Device Spec File/Power Profile File */ 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, sP_power_dn_tl5 = 0, sP_power_dn_tl6 = 0, sP_power_dn_tx = 0, sP_power_dn_rx = 0; ret_val = bm_get_device_network_power_params(&sP_power_dn_tl0, &sP_power_dn_tl1, &sP_power_dn_tl2, &sP_power_dn_tl3, &sP_power_dn_tl4, &sP_power_dn_tl5, &sP_power_dn_tl6, &sP_power_dn_rx, &sP_power_dn_tx); if (ret_val != BATTERY_MONITOR_ERROR_NONE) _ERR("failed to get cpu power params"); _DBG("received device-network power params - signal_0[%lf]\n, signal_1[%lf]\n, signal_2[%lf]\n, \ signal_3[%lf]\n, signal_4[%lf]\n, signal_5[%lf]\n, signal_6[%lf]\n, rx[%lf]\n, tx[%lf]\n", sP_power_dn_tl0, sP_power_dn_tl1, sP_power_dn_tl2, sP_power_dn_tl3, sP_power_dn_tl4, sP_power_dn_tl5, sP_power_dn_tl6, sP_power_dn_rx, sP_power_dn_tx); tl0 /= 1000; tl1 /= 1000; tl2 /= 1000; tl3 /= 1000; tl4 /= 1000; tl5 /= 1000; tl6 /= 1000; tl_total = tl0 + tl1 + tl2 + tl3 + tl4 + tl5 + tl6; /* Device Network power consumption Level - 1 at the Resource Level */ long int P_power_dntw = 0, P_power_data = 0, P_power_conn = 0; P_power_conn = ((sP_power_dn_tl0 * tl0) + (sP_power_dn_tl1 * tl1) + (sP_power_dn_tl2 * tl2) + (sP_power_dn_tl3 * tl3) + (sP_power_dn_tl4 * tl4) + (sP_power_dn_tl5 * tl5) + (sP_power_dn_tl6 * tl6)); P_power_data = ((sP_power_dn_tx) * TX) + ((sP_power_dn_rx) * RX); P_power_dntw = P_power_conn + P_power_data; _DBG("Calculated Power for Device Network P_power_ntw(%ld), P_power_conn (%ld), P_power_data(%ld)", P_power_dntw, P_power_conn, P_power_data); /* Device Network power consumption Level - 2 at the Application Level */ GHashTableIter iter; gpointer key, value; g_hash_table_iter_init(&iter, hash); long int P_power_app_dntw = 0, P_power_app_data = 0, P_power_app_conn = 0; char *appid = NULL; long int apprx = 0, apptx = 0; double apptime = 0; long int ret_time = bm_get_log_time(data_collection_period); long int total_app_pw = 0, base_res_pw = 0; appid_usage_s app_usage; while (g_hash_table_iter_next(&iter, &key, &value)) { P_power_app_dntw = 0; P_power_app_data = 0 ; P_power_app_conn = 0; apprx = 0, apptx = 0, apptime = 0; app_time_map_st2 *temp = (app_time_map_st2 *)value; appid = temp->app_id; apprx = temp->rx; apptx = temp->tx; apptime = temp->time; apptime /= 1000; P_power_app_data = ((sP_power_dn_tx) * apptx) + ((sP_power_dn_rx) * apprx); if (tl_total != 0) P_power_app_conn = (P_power_conn * apptime)/tl_total; //check for 0 denominator & same units P_power_app_dntw = P_power_app_data + P_power_app_conn; app_usage.AppId = appid; app_usage.rId_device_network = P_power_app_dntw; app_usage.log_time = ret_time; total_app_pw += P_power_app_dntw; /* Call Insert Function */ _DBG("Calculated Power for Appid (%s) P_power_app_dntw(%ld), P_power_app_conn (%ld), P_power_app_data(%ld)", appid, P_power_app_dntw, P_power_app_conn, P_power_app_data); if (mode) { ret_val = bm_server_appid_insert_to_db(app_usage.AppId); if (ret_val != BATTERY_MONITOR_ERROR_NONE) _ERR("Insert of DN appid failed "); ret_val = bm_server_app_usage_insert_to_db(&app_usage); } else ret_val = bm_appid_session_usage_map(app_usage.AppId, app_usage.rId_device_network, BM_PLUGIN_ID_DEVICE_NETWORK); if (ret_val != BATTERY_MONITOR_ERROR_NONE) _ERR("Insert of Data Ntwk App failed "); } /* commit to database the output after power calculation */ resourceid_usage_s res_usage; res_usage.ResourceId = BM_RID_DNTW; res_usage.log_time = ret_time; res_usage.usage = P_power_dntw; ret_val = bm_server_resource_usage_insert_to_db(&res_usage); if (ret_val != BATTERY_MONITOR_ERROR_NONE) _ERR("Insert of Data Network resource failed "); if (P_power_dntw > total_app_pw) { base_res_pw = (P_power_dntw - total_app_pw); res_usage.usage = base_res_pw; ret_val = bm_server_resource_base_usage_insert_to_db(&res_usage); if (ret_val != BATTERY_MONITOR_ERROR_NONE) _ERR("Insert of Data Network base resource failed "); } bd_gl_sgt_stat_s *gst_st = (bd_gl_sgt_stat_s *)calloc(1, sizeof(bd_gl_sgt_stat_s)); if (gst_st == NULL) { _ERR("memory allocation failed"); return BATTERY_MONITOR_ERROR_OUT_OF_MEMORY; } gst_st->time_s = ret_time; gst_st->scan_time = tl0; gst_st->none_time = tl1; gst_st->poor_time = tl2; gst_st->med_time = tl3 + tl4; gst_st->good_time = tl5; gst_st->grt_time = tl6; ret_val = bm_server_battery_dump_insert_to_db(gst_st, 4); if (ret_val != BATTERY_MONITOR_ERROR_NONE) _ERR("Insert of GWFL failed "); BM_FREE(gst_st); /* Free the Hash Map */ g_hash_table_destroy(hash); EXIT; return ret_val; } #ifdef DISABLE_FEATURE_DATA_FROM_GPS_HRM_PLUGIN int bm_gps_calc_power_and_commit(bm_gps_st *handle) { ENTER; BM_CHECK_INPUT_PARAM(handle); GSList *gps_data_iterator = NULL; GSList *gps_atm_iterator = NULL; void *prv_data = NULL; void *prv_app_id = NULL; int ret_val = BATTERY_MONITOR_ERROR_NONE; /* creating hash-map with (key, value) = (app-id, data) */ GHashTable *hash = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, NULL); long int edTime = 0; long int stTime = 0; int sesTime = 0; int onTime = 0; /* iterating over list for data accumulation */ for (gps_data_iterator = handle->gps_data_list; gps_data_iterator; gps_data_iterator = gps_data_iterator->next) { bm_gps_st *datalistnode = (bm_gps_st *)(gps_data_iterator->data); edTime = datalistnode->connStartTime; stTime = datalistnode->connStopTime; sesTime = edTime - stTime; gps_atm_iterator = datalistnode->atm_list; for ( ; gps_atm_iterator; gps_atm_iterator = gps_atm_iterator->next) { app_time_map_st1 *gps_atm_node = (app_time_map_st1 *)gps_atm_iterator->data; if (!gps_atm_node) { _DBG("no bt data available"); continue; } _DBG("gps data available"); onTime += gps_atm_node->time; prv_app_id = NULL; prv_data = NULL; if (g_hash_table_lookup_extended(hash, gps_atm_node->app_id, &prv_app_id, &prv_data) == true) { _DBG("previous app_id = %s", (char *)prv_app_id); app_time_map_st1 *gps_atm_prv_node = (app_time_map_st1 *)prv_data; gps_atm_node->time += gps_atm_prv_node->time; _DBG("update - app_id(%s), time(%d)", gps_atm_node->app_id, gps_atm_node->time); _INFO("updated - %d", g_hash_table_replace(hash, gps_atm_node->app_id, gps_atm_node)); } else { _DBG("insert - app_id(%s), time(%d)", gps_atm_node->app_id, gps_atm_node->time); _INFO("inserted - %d", g_hash_table_insert(hash, gps_atm_node->app_id, gps_atm_node)); } } } /* Read standard Rated Values from Device Spec File/Power Profile File */ double sP_power_gps_conn = 0; ret_val = bm_get_gps_sensor_power_params(&sP_power_gps_conn); if (ret_val != BATTERY_MONITOR_ERROR_NONE) _ERR("failed to get gps-sensor power params"); _DBG("gps-sensor power params - gps[%lf]", sP_power_gps_conn); /* GPS power consumption Level - 1 at the Resource Level */ int P_power_gps = 0, P_power_conn = 0; P_power_conn = ((sP_power_gps_conn * sesTime)); P_power_gps = P_power_conn; _DBG("Calculated Power for GPS P_power_gps (%d), P_power_conn (%d)", P_power_gps, P_power_conn); /* GPS power consumption Level - 2 at the Application Level */ GHashTableIter iter; gpointer key, value; g_hash_table_iter_init(&iter, hash); int P_power_app_gps = 0, P_power_app_conn = 0; char *appid = NULL; int apptime = 0; long int ret_time = bm_get_log_time(data_collection_period); long int total_app_pw = 0, base_res_pw = 0; appid_usage_s app_usage; while (g_hash_table_iter_next(&iter, &key, &value)) { P_power_app_gps = 0; P_power_app_conn = 0; apptime = 0; app_time_map_st1 *temp = (app_time_map_st1 *)value; appid = temp->app_id; apptime = temp->time; if (onTime != 0) P_power_app_conn = (P_power_conn * apptime)/onTime; //check for 0 denominator & same units P_power_app_gps = P_power_app_conn; app_usage.AppId = appid; app_usage.rId_gps = P_power_app_gps; app_usage.log_time = ret_time; total_app_pw += P_power_app_gps; /* Call Insert Function */ _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); ret_val = bm_server_app_usage_insert_to_db(&app_usage); if (ret_val != BATTERY_MONITOR_ERROR_NONE) _ERR("Insert of GPS App failed "); } /* commit to database the output after power calculation */ resourceid_usage_s res_usage; res_usage.ResourceId = BM_RID_GPS; res_usage.log_time = ret_time; res_usage.usage = P_power_gps; ret_val = bm_server_resource_usage_insert_to_db(&res_usage); if (ret_val != BATTERY_MONITOR_ERROR_NONE) _ERR("Insert of GPS resource failed "); if (P_power_gps > total_app_pw) { base_res_pw = (P_power_gps - total_app_pw); res_usage.usage = base_res_pw; ret_val = bm_server_resource_base_usage_insert_to_db(&res_usage); if (ret_val != BATTERY_MONITOR_ERROR_NONE) _ERR("Insert of GPS base resource failed "); } /* Free the Hash Map */ g_hash_table_destroy(hash); EXIT; return ret_val; } int bm_hrm_calc_power_and_commit(bm_hrm_sensor_st *handle) { ENTER; BM_CHECK_INPUT_PARAM(handle); GSList *hrm_data_iterator = NULL; GSList *hrm_atm_iterator = NULL; void *prv_data = NULL; void *prv_app_id = NULL; int ret_val = BATTERY_MONITOR_ERROR_NONE; /* creating hash-map with (key, value) = (app-id, data) */ GHashTable *hash = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, NULL); /* iterating over list for data accumulation */ for (hrm_data_iterator = handle->hrm_data_list; hrm_data_iterator; hrm_data_iterator = hrm_data_iterator->next) { hrm_atm_iterator = ((bm_hrm_sensor_st *)(hrm_data_iterator->data))->atm_list; for ( ; hrm_atm_iterator; hrm_atm_iterator = hrm_atm_iterator->next) { app_time_map_st1 *hrm_atm_node = (app_time_map_st1 *)hrm_atm_iterator->data; if (!hrm_atm_node) { _DBG("no bt data available"); continue; } _DBG("hrm data available"); prv_data = NULL; prv_app_id = NULL; if (g_hash_table_lookup_extended(hash, hrm_atm_node->app_id, &prv_app_id, &prv_data) == true) { _DBG("previous app_id = %s", (char *)prv_app_id); app_time_map_st1 *hrm_atm_prv_node = (app_time_map_st1 *)prv_data; hrm_atm_node->time += hrm_atm_prv_node->time; _DBG("update - app_id(%s), time(%d)", hrm_atm_node->app_id, hrm_atm_node->time); _INFO("updated - %d", g_hash_table_replace(hash, hrm_atm_node->app_id, hrm_atm_node)); } else { _DBG("insert - app_id(%s), time(%d)", hrm_atm_node->app_id, hrm_atm_node->time); _INFO("inserted - %d", g_hash_table_insert(hash, hrm_atm_node->app_id, hrm_atm_node)); } } } double sP_power_hrm_conn = 0; /* read hrm-sensor power params */ ret_val = bm_get_hrm_sensor_power_params(&sP_power_hrm_conn); if (ret_val != BATTERY_MONITOR_ERROR_NONE) _ERR("failed to get hrm-sensor power params"); _DBG("hrm-sensor power params - gps[%lf]", sP_power_hrm_conn); /* apply power calculation on the hash-map data*/ /* commit to database the output after power calculation */ /* Free the Hash Map */ g_hash_table_destroy(hash); EXIT; return ret_val; } #endif /* DISABLE_FEATURE_DATA_FROM_GPS_HRM_PLUGIN */ int bm_battery_calc_power_and_commit(void) { ENTER; int ret_val = DEVICE_ERROR_NONE; int battery_percent = 0; bool is_charging = false; ret_val = device_battery_get_percent(&battery_percent); BM_RETURN_VAL((ret_val == DEVICE_ERROR_NONE), {}, BATTERY_MONITOR_ERROR_INTERNAL, "failed to get battery percent"); ret_val = device_battery_is_charging(&is_charging); BM_RETURN_VAL((ret_val == DEVICE_ERROR_NONE), {}, BATTERY_MONITOR_ERROR_INTERNAL, "failed to get charging status"); device_battery_level_e battery_level; ret_val = device_battery_get_level_status(&battery_level); BM_RETURN_VAL((ret_val == DEVICE_ERROR_NONE), {}, BATTERY_MONITOR_ERROR_INTERNAL, "failed to get warning status"); switch (battery_level) { case DEVICE_BATTERY_LEVEL_EMPTY: _DBG("battery level - EMPTY"); break; case DEVICE_BATTERY_LEVEL_CRITICAL: _DBG("battery level - CRITICAL"); break; case DEVICE_BATTERY_LEVEL_LOW: _DBG("battery level - LOW"); break; case DEVICE_BATTERY_LEVEL_HIGH: _DBG("battery level - HIGH"); break; case DEVICE_BATTERY_LEVEL_FULL: _DBG("battery level - FULL"); break; default: _DBG("invalid battery-level"); break; } _INFO("battery percent[%d] & charging status[%s]", battery_percent, (is_charging == true) ? "TRUE" : "FALSE"); int sP_power_battery = 0; ret_val = bm_get_battery_power_params(&sP_power_battery); if (ret_val != BATTERY_MONITOR_ERROR_NONE) _ERR("failed to get battery power params"); _DBG("received battery power params - battery[%d]", sP_power_battery); ret_val = BATTERY_MONITOR_ERROR_NONE; EXIT; return ret_val; } int bm_get_data_from_handles(void) { ENTER; BM_CHECK_INPUT_PARAM(bm_data_handle); BM_CHECK_INPUT_PARAM(bm_req_flag_h); int ret_val = BATTERY_MONITOR_ERROR_NONE; bool mode = false; gl_hash = g_hash_table_new_full(g_str_hash, g_str_equal, bm_data_free, bm_atm_st1_free); if (!gl_hash) _ERR("Global Hash creation failed"); /* parsing ble data */ if (bm_data_handle->bm_ble_handle != NULL && bm_req_flag_h->req_ble_data) { _DBG("parsing ble data"); ret_val = bm_ble_calc_power_and_commit(bm_data_handle->bm_ble_handle, mode); BM_CHECK_VAL((ret_val == BATTERY_MONITOR_ERROR_NONE), "ble power cal failure"); } else { _DBG("set ble flag - true"); bm_engine_set_req_flag_handle(BM_PLUGIN_ID_BLE, true); } _DBG("completed ble data request"); /* parsing wifi data */ if (bm_data_handle->bm_wifi_handle != NULL && bm_req_flag_h->req_wifi_data) { _DBG("parsing wifi data"); ret_val = bm_wifi_calc_power_and_commit(bm_data_handle->bm_wifi_handle, mode); BM_CHECK_VAL((ret_val == BATTERY_MONITOR_ERROR_NONE), "wifi power calc failure"); } else { _DBG("set wifi flag - true"); bm_engine_set_req_flag_handle(BM_PLUGIN_ID_WIFI, true); } _DBG("completed wifi data request"); /* parsing cpu data */ if (bm_data_handle->bm_cpu_handle != NULL && bm_req_flag_h->req_cpu_data) { _DBG("parsing cpu data"); ret_val = bm_cpu_calc_power_and_commit(bm_data_handle->bm_cpu_handle, mode); BM_CHECK_VAL((ret_val == BATTERY_MONITOR_ERROR_NONE), "cpu power calc failure"); } else { _DBG("set cpu flag - true"); bm_engine_set_req_flag_handle(BM_PLUGIN_ID_CPU, true); } _DBG("completed cpu data request"); /* parsing display data */ if (bm_data_handle->bm_display_handle != NULL && bm_req_flag_h->req_dp_data) { _DBG("parsing display data"); ret_val = bm_display_calc_power_and_commit(bm_data_handle->bm_display_handle, mode); BM_CHECK_VAL((ret_val == BATTERY_MONITOR_ERROR_NONE), "display power calc failure"); } else { _DBG("set display flag - true"); bm_engine_set_req_flag_handle(BM_PLUGIN_ID_DISPLAY, true); } _DBG("completed display data request"); /* parsing device-network data */ if (bm_data_handle->bm_dn_handle != NULL && bm_req_flag_h->req_dn_data) { _DBG("parsing device-network data"); ret_val = bm_device_network_calc_power_and_commit(bm_data_handle->bm_dn_handle, mode); BM_CHECK_VAL((ret_val == BATTERY_MONITOR_ERROR_NONE), "device-network power calc failure"); } else { _DBG("set device-network flag - true"); bm_engine_set_req_flag_handle(BM_PLUGIN_ID_DEVICE_NETWORK, true); } _DBG("completed device-network data request"); #ifdef DISABLE_FEATURE_DATA_FROM_GPS_HRM_PLUGIN /* parsing gps data */ if (bm_data_handle->bm_gps_handle != NULL && bm_req_flag_h->req_gps_data) { _DBG("parsing gps data"); ret_val = bm_gps_calc_power_and_commit(bm_data_handle->bm_gps_handle); BM_CHECK_VAL((ret_val == BATTERY_MONITOR_ERROR_NONE), "gps-sensor power calc failure"); } else { _DBG("set gps-sensor flag - true"); bm_engine_set_req_flag_handle(BM_PLUGIN_ID_GPS_SENSOR, true); } _DBG("completed gps data request"); /* parsing hrm data */ if (bm_data_handle->bm_hrm_handle != NULL && bm_req_flag_h->req_hrm_data) { _DBG("parsing hrm data"); ret_val = bm_hrm_calc_power_and_commit(bm_data_handle->bm_hrm_handle); BM_CHECK_VAL((ret_val == BATTERY_MONITOR_ERROR_NONE), "hrm-sensor power calc failure"); } else { _DBG("set hrm-sensor flag - true"); bm_engine_set_req_flag_handle(BM_PLUGIN_ID_HRM_SENSOR, true); } _DBG("completed hrm data request"); #endif /* DISABLE_FEATURE_DATA_FROM_GPS_HRM_PLUGIN */ /* parsing battery data */ _DBG("parsing battery data"); ret_val = bm_battery_calc_power_and_commit(); BM_CHECK_VAL((ret_val == BATTERY_MONITOR_ERROR_NONE), "battery power calc failure"); _DBG("completed battery data request"); ret_val = bm_insert_appid_session_usage_to_db(); BM_CHECK_VAL((ret_val == BATTERY_MONITOR_ERROR_NONE), "battery session logging failure"); /* set free all the data handles */ if (bm_data_handle != NULL) { _DBG("Call Handle Free"); bm_set_free_data_handles(&bm_data_handle); } /* set free global hash values */ if (gl_hash) { g_hash_table_destroy(gl_hash); gl_hash = NULL; } EXIT; return BATTERY_MONITOR_ERROR_NONE; } int bm_start_getting_feature_data(void) { ENTER; int ret_val = BATTERY_MONITOR_ERROR_NONE; int id; bm_plugin_info_h *bm_plugin = NULL; bm_data_h handle = NULL; /* allocate data & flag handle */ if (bm_data_handle == NULL) { bm_data_handle = (bm_feature_data_h)calloc(1, sizeof(struct bm_feature_data_handles_s)); if (!bm_data_handle) { _ERR("memory allocation failed - data handle"); return BATTERY_MONITOR_ERROR_OUT_OF_MEMORY; } } /* request data from each plugin & store its handle */ #ifdef DISABLE_FEATURE_DATA_FROM_GPS_HRM_PLUGIN for (id = BM_PLUGIN_ID_BLE; id < BM_PLUGIN_ID_MAX; ++id) { #else for (id = BM_PLUGIN_ID_BLE; id <= BM_PLUGIN_ID_DEVICE_NETWORK; ++id) { #endif bm_get_feature_plugin_handle(&bm_plugin, id); handle = NULL; if (!bm_plugin || !bm_plugin->api) { _WARN("Plugin with ID: %s is NULL", bm_get_plugin_name(id)); continue; } _INFO(" requesting data from plugin - %s", bm_get_plugin_name(id)); switch (id) { case BM_PLUGIN_ID_BLE: /* BLE Data */ ret_val = bm_plugin->api->get_feature_data(&handle, id); if (ret_val != BATTERY_MONITOR_ERROR_NONE) { _DBG("ble data not available : improper value"); handle = NULL; } if (handle != NULL) { _DBG("received ble data handle"); bm_data_handle->bm_ble_handle = (bm_bluetooth_st *)(handle); } break; case BM_PLUGIN_ID_WIFI: /* WI-FI Data */ ret_val = bm_plugin->api->get_feature_data(&handle, id); if (ret_val != BATTERY_MONITOR_ERROR_NONE) { _DBG("wifi data not available : improper value"); handle = NULL; } if (handle != NULL) { _DBG("received wifi data handle"); bm_data_handle->bm_wifi_handle = (bm_wifi_st *)(handle); } break; case BM_PLUGIN_ID_CPU: /* CPU Data */ ret_val = bm_plugin->api->get_feature_data(&handle, id); if (ret_val != BATTERY_MONITOR_ERROR_NONE) { _DBG("cpu data not available : improper value"); handle = NULL; } if (handle != NULL) { _DBG("received cpu data handle"); bm_data_handle->bm_cpu_handle = (bm_cpu_st *)(handle); } break; case BM_PLUGIN_ID_DISPLAY: /* DISPLAY Data */ ret_val = bm_plugin->api->get_feature_data(&handle, id); if (ret_val != BATTERY_MONITOR_ERROR_NONE) { _DBG("display data not available : improper value"); handle = NULL; } if (handle != NULL) { _DBG("received display data handle"); bm_data_handle->bm_display_handle = (bm_display_st *)(handle); } break; case BM_PLUGIN_ID_DEVICE_NETWORK: /* DEVICE-NETWORK Data */ ret_val = bm_plugin->api->get_feature_data(&handle, id); if (ret_val != BATTERY_MONITOR_ERROR_NONE) { _DBG("device-network data not available : improper value"); handle = NULL; } if (handle != NULL) { _DBG("received device network data handle"); bm_data_handle->bm_dn_handle = (bm_device_network_st *)(handle); } break; #ifdef DISABLE_FEATURE_DATA_FROM_GPS_HRM_PLUGIN case BM_PLUGIN_ID_GPS_SENSOR: /* GPS Sensor Data */ ret_val = bm_plugin->api->get_feature_data(&handle, id); if (ret_val != BATTERY_MONITOR_ERROR_NONE) { _DBG("gps data not available : improper value"); handle = NULL; } if (handle != NULL) { _DBG("received gps data handle"); bm_data_handle->bm_gps_handle = (bm_gps_st *)(handle); } break; case BM_PLUGIN_ID_HRM_SENSOR: /* HRM Sensor Data */ ret_val = bm_plugin->api->get_feature_data(&handle, id); if (ret_val != BATTERY_MONITOR_ERROR_NONE) { _DBG("hrm data not available : improper value"); handle = NULL; } if (handle != NULL) { _DBG("received hrm data handle"); bm_data_handle->bm_hrm_handle = (bm_hrm_sensor_st *)(handle); } break; #endif /* DISABLE_FEATURE_DATA_FROM_GPS_HRM_PLUGIN */ default: break; } } EXIT; return ret_val; } int bm_clean_db_table_for_job_id(void) { ENTER; int ret_val = BATTERY_MONITOR_ERROR_NONE; ret_val = bm_server_delete_table_by_time_interval(); BM_RETURN_VAL((ret_val == BATTERY_MONITOR_ERROR_NONE), {}, BATTERY_MONITOR_ERROR_DB_FAILED, "error in deleting old db data"); EXIT; return ret_val; } /** * We don't use idle time because it can be decreased * when CPU core is inactive. * * Instead, we will use uptime to calculate CPU usage * CPU_USAGE = (CT_USER + CT_NICE + CT_SYSTEM) / (NUM_CORE * UPTIME) */ enum cpu_time { CT_USER = 0, CT_NICE, CT_SYSTEM, // CT_IDLE, CT_NUM }; static int data_collection_try_period = 1000; static int data_collection_accept_count = 5; static double up_time_last; static unsigned long long cpu_time_last[CT_NUM]; int bm_get_cpu_time(unsigned long long cpu_time[CT_NUM]) { int ret_val = 0; FILE *fp = NULL; fp = fopen("/proc/stat", "r"); if (!fp) { _ERR("fopen failed : %m"); return BATTERY_MONITOR_ERROR_NO_DATA; } ret_val = fscanf(fp, "%*s %llu %llu %llu", &cpu_time[CT_USER], &cpu_time[CT_NICE], &cpu_time[CT_SYSTEM]); fclose(fp); if (ret_val < CT_NUM) { _ERR("fscanf failed : %m"); return BATTERY_MONITOR_ERROR_NO_DATA; } return BATTERY_MONITOR_ERROR_NONE; } int bm_get_up_time(double *up_time) { int ret_val = 0; FILE *fp = NULL; fp = fopen("/proc/uptime", "r"); if (!fp) { _ERR("fopen failed : %m"); return BATTERY_MONITOR_ERROR_NO_DATA; } ret_val = fscanf(fp, "%lf", up_time); fclose(fp); if (ret_val < 1) { _ERR("fscanf failed : %m"); return BATTERY_MONITOR_ERROR_NO_DATA; } return BATTERY_MONITOR_ERROR_NONE; } gboolean is_cpu_idle(double usage_ratio_threshold) { static int num_cpu_core = -1; int idx; unsigned long long cpu_time_cur[CT_NUM]; unsigned long long cpu_time_diff[CT_NUM]; double up_time_cur; double up_time_diff; double usage_ratio; if (num_cpu_core < 0) { if (runtime_info_get_processor_count(&num_cpu_core) != RUNTIME_INFO_ERROR_NONE) { _ERR("error getting the number of cpu core"); return FALSE; } } // Get CPU time if (bm_get_cpu_time(cpu_time_cur) != BATTERY_MONITOR_ERROR_NONE) { _ERR("error getting CPU time"); return FALSE; } for (idx = 0; idx < CT_NUM; idx++) { if (cpu_time_last[idx] > cpu_time_cur[idx]) { _ERR("error invalid CPU time"); return FALSE; } cpu_time_diff[idx] = cpu_time_cur[idx] - cpu_time_last[idx]; } for (idx = 0; idx < CT_NUM; idx++) cpu_time_last[idx] = cpu_time_cur[idx]; // Get uptime if (bm_get_up_time(&up_time_cur) != BATTERY_MONITOR_ERROR_NONE) { _ERR("error getting uptime"); return FALSE; } if (up_time_last >= up_time_cur) { _ERR("error invalid uptime"); return FALSE; } up_time_diff = up_time_cur - up_time_last; up_time_last = up_time_cur; // Calculate CPU usage 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); if (usage_ratio > 1.0) usage_ratio = 1.0; if (usage_ratio > usage_ratio_threshold) { _WARN("CPU usage = %.2lf%% (BUSY, criteria[%.2lf%%])", usage_ratio * 100, usage_ratio_threshold * 100); return FALSE; } _DBG("CPU usage = %.2lf%% (IDLE, criteria[%.2lf%%])", usage_ratio * 100, usage_ratio_threshold * 100); return TRUE; } gboolean bm_try_request_feature_data(gpointer data) { enum status { GET_DATA = 0, CALC_AND_STORE, }; static gboolean is_parameter_loaded = FALSE; static int timeout = 60000; static double initial_threshold = 0.60; static double maximum_threshold = 0.70; static double threshold_variance = 0.0; static int remaining_timeout = 60000; static double usage_ratio_threshold = 0.60; static enum status status = GET_DATA; static int idle_count = 0; int ret_val; if (!is_parameter_loaded) { if (bm_get_cpu_usage_checker_params(&timeout, &initial_threshold, &maximum_threshold, &threshold_variance) != BATTERY_MONITOR_ERROR_NONE) { _ERR("error getting cpu usage checker parameters"); return G_SOURCE_REMOVE; } remaining_timeout = timeout; usage_ratio_threshold = initial_threshold; is_parameter_loaded = TRUE; } if (remaining_timeout <= 0) { _DBG("timeout!"); goto request; } remaining_timeout -= data_collection_try_period; if (!is_cpu_idle(usage_ratio_threshold)) { idle_count = 0; if (usage_ratio_threshold < maximum_threshold) usage_ratio_threshold += threshold_variance; return G_SOURCE_CONTINUE; } idle_count++; if (usage_ratio_threshold > initial_threshold) usage_ratio_threshold -= threshold_variance; _DBG("Idle count(%d/%d)", idle_count, data_collection_accept_count); if (idle_count < data_collection_accept_count) return G_SOURCE_CONTINUE; request: idle_count = 0; remaining_timeout = timeout; usage_ratio_threshold = initial_threshold; switch (status) { case GET_DATA: // Request data to plugin ret_val = bm_start_getting_feature_data(); if (ret_val != BATTERY_MONITOR_ERROR_NONE) { _ERR("error requesting feature data"); return G_SOURCE_CONTINUE; } status = CALC_AND_STORE; return G_SOURCE_CONTINUE; case CALC_AND_STORE: // Calculate power consumption and restore to DB ret_val = bm_get_data_from_handles(); if (ret_val != BATTERY_MONITOR_ERROR_NONE) { _ERR("error in parsing data from handles"); return G_SOURCE_CONTINUE; } status = GET_DATA; return G_SOURCE_REMOVE; default: _ERR("error invalid status"); status = GET_DATA; return G_SOURCE_CONTINUE; } } gboolean bm_request_feature_data(gpointer data) { ENTER; int ret_val; ret_val = bm_get_cpu_time(cpu_time_last); if (ret_val != BATTERY_MONITOR_ERROR_NONE) { _ERR("error getting cpu time"); return G_SOURCE_CONTINUE; } ret_val = bm_get_up_time(&up_time_last); if (ret_val != BATTERY_MONITOR_ERROR_NONE) { _ERR("error getting uptime"); return G_SOURCE_CONTINUE; } g_timeout_add(data_collection_try_period, bm_try_request_feature_data, NULL); EXIT; return G_SOURCE_CONTINUE; } gboolean bm_delete_data_from_db(gpointer data) { ENTER; int ret_val = BATTERY_MONITOR_ERROR_NONE; ret_val = bm_clean_db_table_for_job_id(); if (ret_val != BATTERY_MONITOR_ERROR_NONE) _ERR("error cleaning database"); EXIT; return G_SOURCE_CONTINUE; } int initialize_power_engine(void) { ENTER; int ret_val = BATTERY_MONITOR_ERROR_NONE; int delete_db_period = 86400000; bm_req_flag_h = (struct bm_req_feature_data_handle_flag_s *) calloc(1, sizeof(struct bm_req_feature_data_handle_flag_s)); if (!bm_req_flag_h) { _ERR("memory allocation failed - requet flag handle"); return BATTERY_MONITOR_ERROR_OUT_OF_MEMORY; } bm_set_req_flag_handles(true); ret_val = bm_get_job_scheduler_params(&data_collection_period, &data_collection_try_period, &data_collection_accept_count, &delete_db_period); if (ret_val != BATTERY_MONITOR_ERROR_NONE) { _ERR("error getting job scheduler parameters"); return ret_val; } BM_RETURN_VAL((data_collection_period > 0), {}, BATTERY_MONITOR_ERROR_INVALID_PARAMETER, "invalid data collection period"); BM_RETURN_VAL((data_collection_try_period > 0), {}, BATTERY_MONITOR_ERROR_INVALID_PARAMETER, "invalid data collection try period"); BM_RETURN_VAL((data_collection_accept_count > 0), {}, BATTERY_MONITOR_ERROR_INVALID_PARAMETER, "invalid data collection accept count"); BM_RETURN_VAL((delete_db_period > 0), {}, BATTERY_MONITOR_ERROR_INVALID_PARAMETER, "invalid delete db period"); gtimeo_id[0] = 0; gtimeo_id[1] = 0; gtimeo_id[0] = g_timeout_add(data_collection_period, bm_request_feature_data, NULL); gtimeo_id[1] = g_timeout_add(delete_db_period, bm_delete_data_from_db, NULL); _DBG("timeout with id %d and %d added", gtimeo_id[0], gtimeo_id[1]); ret_val = bm_clean_db_table_for_job_id(); if (ret_val != BATTERY_MONITOR_ERROR_NONE) _ERR("error cleaning database"); ret_val = bm_get_battery_power_params(&battery_capacity); if (ret_val != BATTERY_MONITOR_ERROR_NONE) _ERR("unable ro read battery capacity"); battery_capacity *= cmah; //Battery Capacity in mAs EXIT; return ret_val; } void deinitialize_power_engine(void) { ENTER; /* remove timeouts*/ for (int i = 0; i < 2; i++) { if (gtimeo_id[i] != 0) g_source_remove(gtimeo_id[i]); } /* set all data-handle free */ if (bm_data_handle != NULL) { _DBG("setting handle free - deinitializing"); bm_set_free_data_handles(&bm_data_handle); } /* set flag handle free*/ BM_FREE(bm_req_flag_h); EXIT; return; }