Merge "Fix : Adv malfunction on multiple LE connection" into tizen
authorPyun DoHyun <dh79.pyun@samsung.com>
Mon, 30 Mar 2020 02:27:58 +0000 (02:27 +0000)
committerGerrit Code Review <gerrit@review>
Mon, 30 Mar 2020 02:27:58 +0000 (02:27 +0000)
bt-api/bt-adapter-le.c
bt-api/bt-adapter.c
bt-service-adaptation/services/adapter/bt-service-core-adapter-le.c
bt-service-adaptation/services/bt-request-handler.c
bt-service-adaptation/services/bt-service-battery-monitor.c
bt-service-adaptation/services/include/bt-service-battery-monitor.h
bt-service-adaptation/services/include/bt-service-core-adapter-le.h

index 7899e19..86be586 100644 (file)
@@ -93,12 +93,15 @@ BT_EXPORT_API gboolean bluetooth_is_le_scanning(void)
 BT_EXPORT_API int bluetooth_start_le_discovery(void)
 {
        int result;
+       uid_t uid = getuid();
 
        BT_CHECK_ENABLED_ANY(return);
 
        BT_INIT_PARAMS();
        BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
 
+       g_array_append_vals(in_param1, &uid, sizeof(uid_t));
+
        BT_INFO_C("### Start LE scan");
        _bt_print_api_caller_name();
        result = _bt_send_request(BT_BLUEZ_SERVICE, BT_START_LE_DISCOVERY,
@@ -115,12 +118,15 @@ BT_EXPORT_API int bluetooth_start_le_discovery(void)
 BT_EXPORT_API int bluetooth_stop_le_discovery(void)
 {
        int result;
+       uid_t uid = getuid();
 
        BT_CHECK_ENABLED_ANY(return);
 
        BT_INIT_PARAMS();
        BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
 
+       g_array_append_vals(in_param1, &uid, sizeof(uid_t));
+
        BT_INFO_C("### Stop LE scan");
        _bt_print_api_caller_name();
        result = _bt_send_request(BT_BLUEZ_SERVICE, BT_STOP_LE_DISCOVERY,
index 7d0d5be..aeede8e 100644 (file)
@@ -508,6 +508,7 @@ BT_EXPORT_API int bluetooth_start_discovery(unsigned short max_response,
                                            unsigned int classOfDeviceMask)
 {
        int result;
+       uid_t uid = getuid();
 
        BT_CHECK_ENABLED(return);
 
@@ -517,6 +518,7 @@ BT_EXPORT_API int bluetooth_start_discovery(unsigned short max_response,
        g_array_append_vals(in_param1, &max_response, sizeof(unsigned short));
        g_array_append_vals(in_param2, &discovery_duration, sizeof(unsigned short));
        g_array_append_vals(in_param3, &classOfDeviceMask, sizeof(unsigned int));
+       g_array_append_vals(in_param4, &uid, sizeof(uid_t));
 
        result = _bt_send_request(BT_BLUEZ_SERVICE, BT_START_DISCOVERY,
                in_param1, in_param2, in_param3, in_param4, &out_param);
index d10de14..6be2303 100644 (file)
@@ -33,6 +33,7 @@
 #include "bt-service-gatt.h"
 #include "bt-service-util.h"
 #include "bt-service-core-device.h"
+#include "bt-service-battery-monitor.h"
 
 #include <oal-hardware.h>
 #include <oal-manager.h>
@@ -90,6 +91,8 @@ static bt_le_discovery_state_t adapter_le_discovery_state = LE_DISCOVERY_STOPPED
 
 typedef struct {
        char *sender;
+       uid_t uid;
+       pid_t pid;
        GSList *filter_list;
        gboolean is_scanning;
 } bt_adapter_le_scanner_t;
@@ -1980,7 +1983,7 @@ int _bt_unregister_all_scan_filters(const char* sender)
        return BLUETOOTH_ERROR_NONE;
 }
 
-int _bt_start_le_scan(const char *sender)
+int _bt_start_le_scan(const char *sender, uid_t uid, pid_t pid)
 {
        bt_adapter_le_scanner_t *scanner;
        int ret;
@@ -1991,6 +1994,8 @@ int _bt_start_le_scan(const char *sender)
                retv_if(scanner == NULL, BLUETOOTH_ERROR_INTERNAL);
 
                scanner->sender = g_strdup(sender);
+               scanner->uid = uid;
+               scanner->pid = pid;
                scanner_list = g_slist_append(scanner_list, scanner);
        }
 
@@ -2134,6 +2139,8 @@ void _bt_check_le_scanner_app_termination(const char *sender)
        if (scanner->is_scanning)
                _bt_stop_le_scan(sender);
 
+       _bt_bm_remove_scan_app(SCAN_LE, scanner->uid, scanner->pid);
+
        scanner_list = g_slist_remove(scanner_list, scanner);
        g_free(scanner->sender);
        g_free(scanner);
index 93f75bb..4331c5c 100644 (file)
@@ -260,6 +260,24 @@ void _bt_save_invocation_context(GDBusMethodInvocation *invocation, int result,
 
 }
 
+static int __bt_service_get_sender_pid(const char *unique_name, pid_t *pid)
+{
+       int ret;
+       char err_msg[256] = {0, };
+
+       retv_if(bt_service_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
+
+       ret = cynara_creds_gdbus_get_pid(bt_service_conn, unique_name, pid);
+       if (ret != CYNARA_API_SUCCESS) {
+               cynara_strerror(ret, err_msg, sizeof(err_msg));
+               BT_ERR("Fail to get user credential: %s", err_msg);
+
+               return BLUETOOTH_ERROR_INTERNAL;
+       }
+
+       return BLUETOOTH_ERROR_NONE;
+}
+
 static int __bt_bm_request_data(_bt_battery_data_t *latest)
 {
        int ret = _bt_bm_read_data(latest);
@@ -521,6 +539,7 @@ int __bt_bluez_request(int function_name,
                unsigned short max_response;
                unsigned short discovery_duration;
                unsigned int classOfDeviceMask;
+               uid_t uid;
 
                __bt_service_get_parameters(in_param1,
                                &max_response, sizeof(unsigned short));
@@ -528,8 +547,22 @@ int __bt_bluez_request(int function_name,
                                &discovery_duration, sizeof(unsigned short));
                __bt_service_get_parameters(in_param3,
                                &classOfDeviceMask, sizeof(unsigned int));
+               __bt_service_get_parameters(in_param4, &uid, sizeof(uid_t));
 
                result = _bt_start_discovery(max_response, discovery_duration, classOfDeviceMask);
+
+               if (result == BLUETOOTH_ERROR_NONE) {
+                       pid_t pid;
+
+                       sender = (char*)g_dbus_method_invocation_get_sender(context);
+
+                       if (__bt_service_get_sender_pid(sender, &pid) != BLUETOOTH_ERROR_NONE)
+                               BT_ERR("Fail to get the sender pid");
+
+                       BT_DBG("Remeber pid / uid for the scan operation");
+                       _bt_bm_add_scan_app(SCAN_REGACY, uid, pid);
+               }
+
                break;
        }
        case BT_START_CUSTOM_DISCOVERY: {
@@ -3117,21 +3150,46 @@ normal:
        }
 #endif
        case BT_START_LE_DISCOVERY: {
+               uid_t uid = 0;
+               pid_t pid = 0;
+
+               __bt_service_get_parameters(in_param1, &uid, sizeof(uid_t));
+
                sender = (char *)g_dbus_method_invocation_get_sender(context);
-               result = _bt_start_le_scan(sender);
+
+               if (__bt_service_get_sender_pid(sender, &pid) != BLUETOOTH_ERROR_NONE)
+                       BT_ERR("Fail to get the sender pid");
+
+               result = _bt_start_le_scan(sender, uid, pid);
                if (result == BLUETOOTH_ERROR_NONE) {
                        _bt_save_invocation_context(context, result, sender,
                                        function_name, NULL);
+
+                       BT_DBG("Remeber pid / uid for the scan operation");
+                       _bt_bm_add_scan_app(SCAN_LE, uid, pid);
                }
                break;
        }
        case BT_STOP_LE_DISCOVERY: {
+               uid_t uid = 0;
+               pid_t pid = 0;
+
+               __bt_service_get_parameters(in_param1, &uid, sizeof(uid_t));
+
                sender = (char *)g_dbus_method_invocation_get_sender(context);
+
+               if (__bt_service_get_sender_pid(sender, &pid) != BLUETOOTH_ERROR_NONE)
+                       BT_ERR("Fail to get the sender pid");
+
                result = _bt_stop_le_scan(sender);
                if (result == BLUETOOTH_ERROR_NONE) {
                        _bt_save_invocation_context(context, result, sender,
                                        function_name, NULL);
                }
+
+               BT_DBG("Remove pid / uid for the scan operation");
+               _bt_bm_remove_scan_app(SCAN_LE, uid, pid);
+
                break;
        }
        case BT_IS_LE_DISCOVERYING: {
index 59d93cd..e6a360e 100644 (file)
 
 static time_t scan_start = 0;
 static time_t connect_start = 0;
+static time_t app_scan_base = 0;
 static int scan_cnt = 0;
 static int connect_cnt = 0;
 static gboolean is_session_started = FALSE;
 
+static GSList *scan_app_list = NULL;
+
 typedef struct {
         int type;
         void *data;
@@ -46,6 +49,8 @@ typedef struct {
 
 _bt_battery_data_t *current_session_data = NULL;
 
+static void __bt_bm_add_prev_time(uint32_t scan_time);
+
 static void __bt_display_session_data()
 {
        BT_DBG("Displaying session data...");
@@ -62,6 +67,9 @@ int _bt_bm_read_data(_bt_battery_data_t *data)
        uint32_t rx_time = 0;
        uint32_t idle_time = 0;
        uint32_t energy_used = 0;
+       time_t base_time = 0;
+       uint16_t scan_time_per_app = 0;
+       int scan_app_cnt = 0;
 
        BT_DBG("");
 
@@ -89,6 +97,8 @@ int _bt_bm_read_data(_bt_battery_data_t *data)
        if (scan_cnt) {
                data->session_scan_time += (uint16_t) (time(NULL) - scan_start);
                scan_start = time(NULL);
+               base_time = app_scan_base;
+               app_scan_base = scan_start;
        }
 
        data->session_connected_time = current_session_data->session_connected_time;
@@ -97,6 +107,13 @@ int _bt_bm_read_data(_bt_battery_data_t *data)
                connect_start = time(NULL);
        }
 
+       scan_app_cnt = g_slist_length(scan_app_list);
+
+       if (scan_app_cnt > 0) {
+               scan_time_per_app = (uint32_t)(app_scan_base - base_time) / scan_app_cnt;
+               __bt_bm_add_prev_time(scan_time_per_app);
+       }
+
        data->atm_list = current_session_data->atm_list;
        if (data->atm_list == NULL) {
                BT_DBG("No data transaction in this session");
@@ -128,7 +145,7 @@ static GSList* is_app_present(GSList *start, uid_t uid, pid_t pid)
        return NULL;
 }
 
-void _bt_bm_add_transaction_details(uid_t uid, pid_t pid, int size, data_transaction_type_e type)
+void _bt_bm_add_transaction_details(uid_t uid, pid_t pid, int value, data_transaction_type_e type)
 {
        if (current_session_data == NULL) {
                BT_ERR("Session in progress but data structure is not initialized"); //error handling
@@ -143,18 +160,22 @@ void _bt_bm_add_transaction_details(uid_t uid, pid_t pid, int size, data_transac
                app_data->uid = uid;
                app_data->pid = pid;
                if (type == RX_DATA)
-                       app_data->rx_bytes = size;
+                       app_data->rx_bytes = value;
+               else if (type == TX_DATA)
+                       app_data->tx_bytes = value;
                else
-                       app_data->tx_bytes = size;
+                       app_data->time = value;
                current_session_data->atm_list = g_slist_append(current_session_data->atm_list, app_data);
        }
        else {
                BT_INFO("Match found, updating existing node...");
                app_data = (_bt_battery_app_data_t *)(t->data);
                if (type == RX_DATA)
-                       app_data->rx_bytes += size;
+                       app_data->rx_bytes += value;
+               else if (type == TX_DATA)
+                       app_data->tx_bytes += value;
                else
-                       app_data->tx_bytes += size;
+                       app_data->time += value;
        }
 }
 
@@ -189,12 +210,154 @@ void _bt_stop_session_time()
        __bt_display_session_data();
 }
 
+/* 1 app can operate the regacy and ble scan at the same time */
+static GSList* __is_scan_app_present(GSList *start, bt_bm_scan_type_e type, uid_t uid, pid_t pid)
+{
+       GSList *l = NULL;
+       bt_bm_scan_info_t *t;
+
+       for (l = start; l != NULL; l = g_slist_next(l)) {
+               t = (bt_bm_scan_info_t *)(l->data);
+
+               /* Find the regacy scan app for Inquiry stop */
+               if (type == SCAN_REGACY && t->type != SCAN_LE) {
+                       BT_INFO("app already exist");
+                       return l;
+               }
+
+               if (t->uid == uid && t->pid == pid) {
+                       BT_INFO("app already exist");
+                       return l;
+               }
+       }
+       return NULL;
+}
+
+static void __bt_bm_add_prev_time(uint32_t scan_time)
+{
+       GSList *l = NULL;
+       bt_bm_scan_info_t *t;
+
+       for (l = scan_app_list; l != NULL; l = g_slist_next(l)) {
+               t = (bt_bm_scan_info_t *)(l->data);
+               _bt_bm_add_transaction_details(t->uid, t->pid, scan_time, TIME_DATA);
+       }
+}
+
+/* 1 regacy scan is only allowed in the platform
+ * BLE scan is allowed for many apps
+*/
+/* When a app is added, we should add and reset the time. */
+void _bt_bm_add_scan_app(bt_bm_scan_type_e type, uid_t uid, pid_t pid)
+{
+       bt_bm_scan_info_t *scan_info = NULL;
+       GSList *app_list = NULL;
+       int app_cnt = 0;
+       time_t base_time = 0;
+       uint16_t scan_time_per_app = 0;
+
+       BT_DBG("Scan type: %d", type);
+
+       /* Update the base time */
+       base_time = app_scan_base;
+       app_scan_base = time(NULL);
+
+       if (scan_app_list) {
+               app_cnt = g_slist_length(scan_app_list);
+               app_list = __is_scan_app_present(scan_app_list, SCAN_BOTH, uid, pid);
+       }
+
+       if (app_list) {
+               /* app try to scan both Regacy and LE */
+               scan_info = (bt_bm_scan_info_t *)(app_list->data);
+
+               if (scan_info == NULL) {
+                       BT_ERR("Can't get the scan info");
+                       return;
+               }
+
+               BT_DBG("Previous type: %d", scan_info->type);
+
+               if (scan_info->type == type) {
+                       BT_ERR("Same scan type is doing");
+                       return;
+               }
+
+               scan_info->type = SCAN_BOTH;
+       } else {
+               scan_info = g_malloc0(sizeof(bt_bm_scan_info_t));
+               scan_info->uid = uid;
+               scan_info->pid = pid;
+               scan_info->type = type;
+
+               if (app_cnt > 0 && base_time != 0) {
+                       /* Update the base time */
+                       base_time = app_scan_base;
+                       app_scan_base = time(NULL);
+
+                       scan_time_per_app = (uint32_t)(app_scan_base - base_time) / app_cnt;
+                       __bt_bm_add_prev_time(scan_time_per_app);
+               }
+
+               scan_app_list = g_slist_append(scan_app_list, scan_info);
+       }
+}
+
+/* When a app is removed, we should add and reset the time. */
+void _bt_bm_remove_scan_app(bt_bm_scan_type_e type, uid_t uid, pid_t pid)
+{
+       bt_bm_scan_info_t *scan_info = NULL;
+       GSList *app_list = NULL;
+       int app_cnt = 0;
+       time_t base_time = 0;
+       uint16_t scan_time_per_app = 0;
+
+       BT_DBG("Scan type: %d", type);
+
+       if (scan_app_list == NULL) {
+               BT_ERR("No scan app in list");
+               return;
+       }
+
+       app_cnt = g_slist_length(scan_app_list);
+
+       if (app_cnt == 0) {
+               BT_ERR("No scan app in list");
+               return;
+       }
+
+       app_list = __is_scan_app_present(scan_app_list, type, uid, pid);
+
+       if (app_list) {
+               scan_info = (bt_bm_scan_info_t *)(app_list->data);
+
+               if (scan_info->type == SCAN_BOTH) {
+                       scan_info->type = (scan_info->type == SCAN_REGACY) ? SCAN_LE : SCAN_REGACY;
+                       return;
+               }
+
+               /* Update the base time */
+               base_time = app_scan_base;
+               app_scan_base = time(NULL);
+
+               if (base_time != 0) {
+                       scan_time_per_app = (uint32_t)(app_scan_base - base_time) / app_cnt;
+                       __bt_bm_add_prev_time(scan_time_per_app);
+               }
+
+               scan_app_list = g_slist_remove(scan_app_list, scan_info);
+
+               g_free(scan_info);
+       }
+}
+
 void _bt_start_scan_time()
 {
        if (current_session_data != NULL) {
                if (scan_cnt == 0) {
                        BT_DBG("Starting scan time");
                        scan_start = time(NULL);
+                       app_scan_base = scan_start;
                }
                scan_cnt++;
        } else {
@@ -211,6 +374,8 @@ void _bt_stop_scan_time()
                if(scan_cnt == 0) {
                        time_t temp = time(NULL);
                        current_session_data->session_scan_time += (uint16_t) (temp - scan_start);
+                       scan_start = 0;
+                       app_scan_base = scan_start;
                }
        }
 }
@@ -316,6 +481,11 @@ void _bt_bm_event_handler(gpointer data)
                _bt_start_scan_time();
                break;
        case OAL_EVENT_ADAPTER_INQUIRY_FINISHED:
+               /* Remove the regacy scan app */
+               _bt_bm_remove_scan_app(SCAN_REGACY, 0, 0);
+
+               _bt_stop_scan_time();
+               break;
        case OAL_EVENT_BLE_DISCOVERY_STOPPED:
                BT_DBG("Handling Adapter Discovery Stop");
                _bt_stop_scan_time();
index 784d4ba..7e227f8 100644 (file)
@@ -50,8 +50,21 @@ typedef struct {
 } _bt_battery_data_t;
 
 typedef enum {
+       SCAN_REGACY = 0x00,
+       SCAN_LE,
+       SCAN_BOTH
+} bt_bm_scan_type_e;
+
+typedef struct {
+       bt_bm_scan_type_e type;
+       uid_t uid;
+       pid_t pid;
+} bt_bm_scan_info_t;
+
+typedef enum {
        RX_DATA,
-       TX_DATA
+       TX_DATA,
+       TIME_DATA
 } data_transaction_type_e;
 
 void _bt_bm_event_handler(gpointer data);
@@ -60,6 +73,10 @@ int _bt_bm_read_data(_bt_battery_data_t *data);
 
 void _bt_bm_add_transaction_details(uid_t uid, pid_t pid, int size, data_transaction_type_e type);
 
+void _bt_bm_add_scan_app(bt_bm_scan_type_e type, uid_t uid, pid_t pid);
+
+void _bt_bm_remove_scan_app(bt_bm_scan_type_e type, uid_t uid, pid_t pid);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
index 609f88f..0e41726 100644 (file)
@@ -82,7 +82,7 @@ int _bt_get_advertising_data(char *sender, int adv_handle, bluetooth_advertising
 
 int _bt_get_scan_response_data(char *sender, int adv_handle, bluetooth_scan_resp_data_t *adv, int *length);
 
-int _bt_start_le_scan(const char *sender);
+int _bt_start_le_scan(const char *sender, uid_t uid, pid_t pid);
 
 int _bt_stop_le_scan(const char *sender);