Increase the session timeout value
[platform/core/connectivity/bluetooth-frwk.git] / bt-service-adaptation / services / bt-service-battery-monitor.c
index ce452ed..16bd835 100644 (file)
@@ -25,6 +25,7 @@
 #include <dlog.h>
 #include <time.h>
 #include <sys/time.h>
+#include <vconf.h>
 
 #include <oal-event.h>
 
 #include "bt-service-event.h"
 #include "bt-service-core-adapter.h"
 
+/* Avoid the build error related to vconf.h's dependency */
+#ifndef VCONFKEY_BATTERY_MONITOR_STATUS
+#define VCONFKEY_BATTERY_MONITOR_STATUS "db/bluetooth/bmstatus"
+#endif
+
+/* 20 minutes */
+#define BT_BM_SESSION_TIMEOUT 1200
+
 static struct timeval scan_start;
 static struct timeval connect_start;
 static struct timeval app_scan_base;
 static int scan_cnt = 0;
 static int connect_cnt = 0;
 static gboolean is_session_started = FALSE;
+static guint session_timer = 0;
 
 static GSList *scan_app_list = NULL;
 
@@ -50,6 +60,9 @@ typedef struct {
 _bt_battery_data_t *current_session_data = NULL;
 
 static void __bt_bm_add_prev_time(uint32_t scan_time);
+static int __bt_start_session_time(void);
+static void __bt_stop_session_time(void);
+static bool __bt_bm_session_timeout_cb(void);
 
 uint32_t static __bt_dm_time_diff_msec(struct timeval prev, struct timeval cur)
 {
@@ -59,6 +72,12 @@ uint32_t static __bt_dm_time_diff_msec(struct timeval prev, struct timeval cur)
 static void __bt_display_session_data()
 {
        BT_DBG("Displaying session data...");
+
+       if (current_session_data == NULL) {
+               BT_ERR("Session in progress but data structure is not initialized");
+               return;
+       }
+
        BT_DBG("session_start_time = %ld", current_session_data->session_start_time);
        BT_DBG("session_end_time = %ld", current_session_data->session_end_time);
        BT_DBG("session_scan_time = %d", current_session_data->session_scan_time);
@@ -89,6 +108,18 @@ int _bt_bm_read_data(_bt_battery_data_t *data)
                return BLUETOOTH_ERROR_NOT_SUPPORT;
        }
 
+       if (is_session_started == FALSE) {
+               if (__bt_start_session_time() != BLUETOOTH_ERROR_NONE) {
+                       BT_ERR("Fail to start session time");
+                       return BLUETOOTH_ERROR_NOT_SUPPORT;
+               }
+       }
+
+       if (current_session_data == NULL) {
+               BT_ERR("Session in progress but data structure is not initialized");
+               return BLUETOOTH_ERROR_INTERNAL;
+       }
+
        gettimeofday(&cur_time, 0);
 
        data->tx_time = tx_time;
@@ -123,11 +154,9 @@ int _bt_bm_read_data(_bt_battery_data_t *data)
 
        gettimeofday(&app_scan_base, 0);
 
-       data->atm_list = current_session_data->atm_list;
-       if (data->atm_list == NULL) {
-               BT_DBG("No data transaction in this session");
-               return BLUETOOTH_ERROR_NONE;
-       }
+       /* Note that this is a "shallow" copy. The pointers are copied but the actual data isn't. */
+       data->atm_list = g_slist_copy(current_session_data->atm_list);
+       current_session_data->atm_list = NULL;
 
        BT_DBG("App-wise data transaction details");
        for (GSList *l = data->atm_list; l != NULL; l = g_slist_next(l)) {
@@ -135,7 +164,13 @@ int _bt_bm_read_data(_bt_battery_data_t *data)
                BT_DBG("%ld %ld %d %d %u", (long int)(t->uid), (long int)(t->pid), t->rx_bytes, t->tx_bytes, t->time);
        }
 
-       current_session_data->atm_list = NULL;
+       /* Reset the session timer */
+       if (session_timer)
+               g_source_remove(session_timer);
+
+       session_timer = g_timeout_add_seconds(BT_BM_SESSION_TIMEOUT,
+                               (GSourceFunc)__bt_bm_session_timeout_cb, NULL);
+
        return BLUETOOTH_ERROR_NONE;
 }
 
@@ -156,8 +191,11 @@ static GSList* is_app_present(GSList *start, uid_t uid, pid_t pid)
 
 void _bt_bm_add_transaction_details(uid_t uid, pid_t pid, int value, data_transaction_type_e type)
 {
+       if (is_session_started == FALSE)
+               __bt_start_session_time();
+
        if (current_session_data == NULL) {
-               BT_ERR("Session in progress but data structure is not initialized"); //error handling
+               BT_ERR("Session in progress but data structure is not initialized");
                return;
        }
        GSList *t = is_app_present(current_session_data->atm_list, uid, pid);
@@ -188,35 +226,81 @@ void _bt_bm_add_transaction_details(uid_t uid, pid_t pid, int value, data_transa
        }
 }
 
-void _bt_start_session_time()
+static bool __bt_bm_session_timeout_cb(void)
 {
-       if (is_session_started == FALSE) {
-               BT_DBG("Bt session starting...");
-               is_session_started = TRUE;
-               current_session_data = g_malloc0(sizeof(_bt_battery_data_t));
-               current_session_data->session_start_time = time(NULL);
-               current_session_data->session_end_time = 0;
-               current_session_data->session_connected_time = 0;
-               current_session_data->session_scan_time = 0;
-               current_session_data->atm_list = NULL;
-       } else {
-               if (current_session_data == NULL)
-                       BT_ERR("Session in progress but data structure is not initialized"); //error handling
-               else
-                       BT_DBG("Bt session already in progress... Returning");
+       BT_INFO("No data read calls during the time.");
+
+       __bt_stop_session_time();
+
+       return FALSE;
+}
+
+
+static int __bt_start_session_time(void)
+{
+       int state = 0;
+
+       if (is_session_started == TRUE) {
+               BT_ERR("Session is already started");
+               return BLUETOOTH_ERROR_ALREADY_INITIALIZED;
+       }
+
+       if (vconf_get_bool(VCONFKEY_BATTERY_MONITOR_STATUS, &state) != 0) {
+               BT_ERR("vconf_get_bool failed");
+               return BLUETOOTH_ERROR_INTERNAL;
+       }
+
+       if (state == 0) {
+               BT_ERR("Battery is not monitoring in now");
+               return BLUETOOTH_ERROR_NOT_SUPPORT;
        }
+
+       BT_DBG("Bt session starting...");
+       is_session_started = TRUE;
+
+       if (current_session_data == NULL)
+               current_session_data = g_malloc0(sizeof(_bt_battery_data_t));
+
+       current_session_data->session_start_time = time(NULL);
+       current_session_data->session_end_time = 0;
+       current_session_data->session_connected_time = 0;
+       current_session_data->session_scan_time = 0;
+       current_session_data->atm_list = NULL;
+
+       /* After starting session if there is no read data call during the specific time,
+        * stop the session time to avoid the exceed of session data.
+       */
+       if (session_timer)
+               g_source_remove(session_timer);
+
+       session_timer = g_timeout_add_seconds(BT_BM_SESSION_TIMEOUT,
+                               (GSourceFunc)__bt_bm_session_timeout_cb, NULL);
+
+       return BLUETOOTH_ERROR_NONE;
 }
 
-void _bt_stop_session_time()
+static void __bt_stop_session_time(void)
 {
+       if (session_timer) {
+               g_source_remove(session_timer);
+               session_timer = 0;
+       }
+
        if (is_session_started == FALSE) {
-               BT_DBG("BT session not in progress... Returning"); //error handling
+               BT_DBG("BT session not in progress... Returning");
                return;
        }
+
+       __bt_display_session_data();
+
        BT_DBG("Bt session ending...");
        is_session_started = FALSE;
-       current_session_data->session_end_time = time(NULL);
-       __bt_display_session_data();
+
+       if (current_session_data != NULL) {
+               g_slist_free_full(current_session_data->atm_list, g_free);
+               g_free(current_session_data);
+               current_session_data = NULL;
+       }
 }
 
 /* 1 app can operate the regacy and ble scan at the same time */
@@ -360,6 +444,13 @@ void _bt_bm_remove_scan_app(bt_bm_scan_type_e type, uid_t uid, pid_t pid)
 
 void _bt_start_scan_time()
 {
+       if (is_session_started == FALSE) {
+               if (__bt_start_session_time() != BLUETOOTH_ERROR_NONE) {
+                       BT_ERR("Fail to start session time");
+                       return;
+               }
+       }
+
        if (current_session_data != NULL) {
                if (scan_cnt == 0) {
                        BT_DBG("Starting scan time");
@@ -368,14 +459,21 @@ void _bt_start_scan_time()
                }
                scan_cnt++;
        } else {
-               BT_ERR("Data structure uninitialized"); //error handling
+               BT_ERR("Data structure uninitialized");
        }
 }
 
 void _bt_stop_scan_time()
 {
+       if (is_session_started == FALSE) {
+               if (__bt_start_session_time() != BLUETOOTH_ERROR_NONE) {
+                       BT_ERR("Fail to start session time");
+                       return;
+               }
+       }
+
        if (scan_cnt == 0 || current_session_data == NULL)
-               BT_ERR("Error encountered, returning..."); //error handling
+               BT_ERR("Error encountered, returning...");
        else {
                scan_cnt--;
                if(scan_cnt == 0) {
@@ -391,6 +489,13 @@ void _bt_stop_scan_time()
 
 void _bt_start_connect_time()
 {
+       if (is_session_started == FALSE) {
+               if (__bt_start_session_time() != BLUETOOTH_ERROR_NONE) {
+                       BT_ERR("Fail to start session time");
+                       return;
+               }
+       }
+
        if (current_session_data != NULL) {
                if (connect_cnt == 0) {
                        BT_DBG("Starting connect time");
@@ -399,16 +504,22 @@ void _bt_start_connect_time()
                connect_cnt++;
        }
        else {
-               BT_ERR("Data structure uninitialized"); //error handling
+               BT_ERR("Data structure uninitialized");
        }
 }
 
 void _bt_stop_connect_time()
 {
-       if(connect_cnt == 0 || current_session_data == NULL) {
-               BT_ERR("Error encountered, returning..."); //error handling
+       if (is_session_started == FALSE) {
+               if (__bt_start_session_time() != BLUETOOTH_ERROR_NONE) {
+                       BT_ERR("Fail to start session time");
+                       return;
+               }
        }
-       else {
+
+       if(connect_cnt == 0 || current_session_data == NULL) {
+               BT_ERR("Error encountered, returning...");
+       } else {
                connect_cnt--;
                if(connect_cnt == 0) {
                        struct timeval cur_time;
@@ -419,7 +530,7 @@ void _bt_stop_connect_time()
        }
 }
 
-static void _bt_notify_battery_data(void)
+static void __bt_notify_battery_data(void)
 {
        BT_INFO("+");
        _bt_battery_data_t *data = NULL;
@@ -432,40 +543,42 @@ static void _bt_notify_battery_data(void)
 
        if (result != BLUETOOTH_ERROR_NONE) {
                BT_ERR("Battery data not collected");
+               g_free(data);
+               return;
        }
-       else {
-               bt_battery_dbus_data_t dbus_data;
-               memset(&dbus_data, 0, sizeof(bt_battery_dbus_data_t));
-               dbus_data.session_start_time = data->session_start_time;
-               dbus_data.session_end_time = data->session_end_time;
-               dbus_data.session_scan_time = data->session_scan_time;
-               dbus_data.session_connected_time = data->session_connected_time;
-               dbus_data.tx_time = data->tx_time;
-               dbus_data.rx_time = data->rx_time;
-               dbus_data.idle_time = data->idle_time;
-
-               /*Populating app data*/
-               int n = 0;
-               for (GSList *l = data->atm_list; l != NULL; l = g_slist_next(l)) {
-                       bt_battery_app_data *t = (bt_battery_app_data *)(l->data);
-                       memcpy(&dbus_data.app_data[n], t, sizeof(bt_battery_app_data));
-                       n++;
-               }
-               dbus_data.num_app = n;
-
-               info = g_array_new(FALSE, FALSE, sizeof(gchar));
-               g_array_append_vals(info, &dbus_data, sizeof(bt_battery_dbus_data_t));
 
-               out_var = g_variant_new_from_data((const GVariantType *)"ay",
-                               info->data, info->len,
-                               TRUE, NULL, NULL);
+       bt_battery_dbus_data_t dbus_data;
+       memset(&dbus_data, 0, sizeof(bt_battery_dbus_data_t));
+       dbus_data.session_start_time = data->session_start_time;
+       dbus_data.session_end_time = data->session_end_time;
+       dbus_data.session_scan_time = data->session_scan_time;
+       dbus_data.session_connected_time = data->session_connected_time;
+       dbus_data.tx_time = data->tx_time;
+       dbus_data.rx_time = data->rx_time;
+       dbus_data.idle_time = data->idle_time;
+
+       /*Populating app data*/
+       int n = 0;
+       for (GSList *l = data->atm_list; l != NULL; l = g_slist_next(l)) {
+               bt_battery_app_data *t = (bt_battery_app_data *)(l->data);
+               memcpy(&dbus_data.app_data[n], t, sizeof(bt_battery_app_data));
+               n++;
        }
+       dbus_data.num_app = n;
+
+       info = g_array_new(FALSE, FALSE, sizeof(gchar));
+       g_array_append_vals(info, &dbus_data, sizeof(bt_battery_dbus_data_t));
+
+       out_var = g_variant_new_from_data((const GVariantType *)"ay",
+                       info->data, info->len,
+                       TRUE, NULL, NULL);
+
        param = g_variant_new("(iv)", result, out_var);
        _bt_send_event(BT_ADAPTER_EVENT,
                BLUETOOTH_EVENT_DISABLED_BATTERY_DATA,
                param);
 
-       g_slist_free(data->atm_list);
+       g_slist_free_full(data->atm_list, g_free);
        g_free(data);
        g_array_free(info, TRUE);
        BT_INFO("-");
@@ -479,12 +592,15 @@ void _bt_bm_event_handler(gpointer data)
        switch(event_type) {
        case OAL_EVENT_ADAPTER_ENABLED:
                BT_DBG("Handling Adapter Enabled");
-               _bt_start_session_time();
+               if (__bt_start_session_time() != BLUETOOTH_ERROR_NONE)
+                       BT_ERR("Fail to start session time");
                break;
        case OAL_EVENT_ADAPTER_DISABLED:
                BT_DBG("Handling Adapter Disabled");
-               _bt_stop_session_time();
-               _bt_notify_battery_data();
+               if (is_session_started == TRUE) {
+                       __bt_notify_battery_data();
+                       __bt_stop_session_time();
+               }
                break;
        case OAL_EVENT_ADAPTER_INQUIRY_STARTED:
        case OAL_EVENT_BLE_DISCOVERY_STARTED: