Apply high scan duty implementation 54/322954/3 accepted/tizen_7.0_unified tizen_7.0 accepted/tizen/7.0/unified/20250530.072044
authorJihoon Jung <jh8801.jung@samsung.com>
Wed, 19 Feb 2025 07:39:10 +0000 (16:39 +0900)
committerBhabesh <bhabesh.km@partner.samsung.com>
Wed, 14 May 2025 12:37:14 +0000 (18:07 +0530)
Change-Id: I4d847d837ef1b3fa4a664cde5a1e065219cbaad7
Signed-off-by: Jihoon Jung <jh8801.jung@samsung.com>
Signed-off-by: Bhabesh Kumar <bhabesh.km@partner.samsung.com>
bt-service/services/adapter/bt-service-core-adapter-le.c
bt-service/services/bt-request-handler.c
bt-service/services/include/bt-service-core-adapter-le.h

index 1f9454ec4b965d441203a7c2b83efdd63c0d3956..814e83f833335a2ac773a627421862e74ab49a2e 100644 (file)
@@ -103,6 +103,7 @@ typedef struct {
        pid_t pid;
        GSList *filter_list;
        gboolean is_scanning;
+       bluetooth_le_scan_params_t scan_params;
 } bt_adapter_le_scanner_t;
 
 static GSList *scanner_list = NULL;
@@ -113,6 +114,7 @@ static gboolean is_le_scan_hold = FALSE;
 static gboolean scan_filter_enabled = FALSE;
 static gboolean scan_stop_requested = FALSE;
 static gboolean is_mesh_le_scan_stop_hold = FALSE;
+static gboolean is_set_scan_parameter_in_progress = FALSE;
 
 static bluetooth_le_scan_params_t le_scan_params = { BT_LE_ACTIVE_SCAN, 0, 0 };
 
@@ -197,6 +199,73 @@ static void __bt_le_handle_pending_requests(int service_function, void *user_dat
        }
 }
 
+static bluetooth_le_scan_params_t * __bt_get_high_duty_scan_params()
+{
+       GSList *node;
+       bt_adapter_le_scanner_t *scanner = NULL, *selected_scanner = NULL;
+       float highest_scan_duty = 0, scan_duty = 0;
+
+       for (node = scanner_list; node != NULL; node = g_slist_next(node)) {
+               scanner = node->data;
+
+               if (FALSE == scanner->is_scanning)
+                       continue;
+
+               scan_duty = scanner->scan_params.window / scanner->scan_params.interval;
+               BT_DBG("scanning scanner - duty = %f, sender %s, itv %f, win %f", scan_duty, scanner->sender, scanner->scan_params.interval, scanner->scan_params.window);
+
+               if (highest_scan_duty < scan_duty) {
+                       highest_scan_duty = scan_duty;
+                       selected_scanner = scanner;
+               }
+       }
+
+       if (selected_scanner) {
+               BT_INFO("high duty scanner - sender %s, itv %f, win %f", selected_scanner->sender, selected_scanner->scan_params.interval, selected_scanner->scan_params.window);
+               return &selected_scanner->scan_params;
+       }
+
+       return NULL;
+}
+
+static bool __bt_validateParams(bluetooth_le_scan_params_t current_scan_params)
+{
+       bluetooth_le_scan_params_t *high_duty_params = NULL;
+       float highest_scan_duty = 0;
+       float current_scan_duty = 0;
+
+       current_scan_duty= current_scan_params.window/current_scan_params.interval;
+       high_duty_params = __bt_get_high_duty_scan_params();
+       if (high_duty_params == NULL) {
+               BT_DBG("No high duty scan parameters available");
+               return false;
+       }
+       highest_scan_duty = high_duty_params->window/high_duty_params->interval;
+       if (current_scan_duty <= highest_scan_duty) {
+               return true;
+       }
+       return false;
+}
+
+static void __bt_set_highest_scan_parameters()
+{
+       oal_status_t result = 0;
+       bluetooth_le_scan_params_t *scan_params;
+       int itv, win;
+
+       scan_params = __bt_get_high_duty_scan_params();
+
+       if (NULL == scan_params) {
+               BT_DBG("no high duty scan param");
+               return;
+       }
+
+       itv = scan_params->interval / BT_ADV_INTERVAL_SPLIT;
+       win = scan_params->window / BT_ADV_INTERVAL_SPLIT;
+       result = gattc_set_le_scan_param(scan_params->type, itv, win);
+       if (OAL_STATUS_SUCCESS != result)
+               BT_INFO("gattc_set_le_scan_param [%d] failed", result);
+}
 
 /* Request return handlings */
 static gboolean __bt_le_post_set_enabled(gpointer user_data)
@@ -1077,6 +1146,14 @@ static void __bt_le_event_handler(int event_type, gpointer event_data)
                }
 
                _bt_set_le_scan_stop_requested(FALSE);
+
+               if (is_set_scan_parameter_in_progress) {
+                       BT_ERR("Currently set_scan_parameter is in progress.");
+                       is_set_scan_parameter_in_progress = FALSE;
+                       _bt_restart_le_scan();
+                       break;
+               }
+
                if (is_le_scan_hold == TRUE)
                        break;
                __bt_set_le_scan_status(FALSE);
@@ -1903,11 +1980,14 @@ int _bt_set_scan_response_data(const char *sender, int adv_handle,
 }
 
 /*************************************** LE Scan APIs *********************************************/
-int _bt_set_scan_parameters(bluetooth_le_scan_params_t *params)
+int _bt_set_scan_parameters(const char *sender, bluetooth_le_scan_params_t *params)
 {
        int itv = 0;
        int win = 0;
        int ret;
+       bt_adapter_le_scanner_t *scanner = NULL;
+       bluetooth_le_scan_params_t selected_scan_params, *high_duty_params = NULL;
+       float highest_scan_duty = 0, requested_scan_duty = 0;
 
        BT_CHECK_PARAMETER(params, return);
 
@@ -1929,15 +2009,54 @@ int _bt_set_scan_parameters(bluetooth_le_scan_params_t *params)
        if (params->window > params->interval)
                return BLUETOOTH_ERROR_INVALID_PARAM;
 
-       itv = params->interval / BT_SCAN_INTERVAL_SPLIT;
-       win = params->window / BT_SCAN_INTERVAL_SPLIT;
+       if (sender) {
+               scanner = __bt_find_scanner_from_list(sender);
+               if (NULL == scanner) {
+                       scanner = g_malloc0(sizeof(bt_adapter_le_scanner_t));
+                       retv_if(scanner == NULL, BLUETOOTH_ERROR_INTERNAL);
+
+                       scanner->sender = g_strdup(sender);
+
+                       scanner->scan_params.type = params->type;
+                       scanner->scan_params.interval = params->interval;
+                       scanner->scan_params.window = params->window;
+
+                       scanner_list = g_slist_append(scanner_list, scanner);
+               } else {
+                       scanner->scan_params = *params;
+               }
+       }
+
+       high_duty_params = __bt_get_high_duty_scan_params();
+
+       if (high_duty_params) {
+               highest_scan_duty = high_duty_params->window / high_duty_params->interval;
+               requested_scan_duty = params->window / params->interval;
+               if (requested_scan_duty > highest_scan_duty) {
+                       selected_scan_params = *params;
+               } else {
+                       selected_scan_params = *high_duty_params;
+               }
+       } else {
+               selected_scan_params = *params;
+       }
+
+       BT_INFO("Set scan parameters - itv %f, win %f, type %d", selected_scan_params.interval, selected_scan_params.window, selected_scan_params.type);
+
+       selected_scan_params.interval /= BT_ADV_INTERVAL_SPLIT;
+       selected_scan_params.window /= BT_ADV_INTERVAL_SPLIT;
 
-       ret = gattc_set_le_scan_param(params->type, itv, win);
+       if (is_le_scan_hold)
+               is_set_scan_parameter_in_progress = TRUE;
+
+       ret = gattc_set_le_scan_param(selected_scan_params.type, selected_scan_params.interval, selected_scan_params.window);
        if (OAL_STATUS_SUCCESS != ret) {
                BT_ERR("gattc_set_le_scan_param failed");
                return _bt_convert_oal_status_to_bt_error(ret);
        }
 
+       is_le_set_scan_parameter = TRUE;
+
        BT_INFO("Set scan parameters inteval %f, win %f, type %d",
                        itv * BT_SCAN_INTERVAL_SPLIT, win * BT_SCAN_INTERVAL_SPLIT, params->type);
 
@@ -2146,6 +2265,12 @@ int _bt_start_le_scan(const char *sender, uid_t uid, pid_t pid)
                return BLUETOOTH_ERROR_IN_PROGRESS;
        }
 
+       if (scanner->scan_params.interval == 0) {
+               scanner->scan_params.type = BT_LE_ACTIVE_SCAN;
+               scanner->scan_params.interval = BT_LE_SCAN_LOW_ENERGY_INTERVAL;
+               scanner->scan_params.window = BT_LE_SCAN_LOW_ENERGY_WINDOW;
+       }
+
        scanner->is_scanning = TRUE;
 
        /* Check scanning is in progress or not by other users */
@@ -2173,13 +2298,8 @@ int _bt_start_le_scan(const char *sender, uid_t uid, pid_t pid)
                return BLUETOOTH_ERROR_NONE;
        } else {
                if (is_le_set_scan_parameter == FALSE) {
-                       /* Set default scan parameter same with BT_ADAPTER_LE_SCAN_MODE_LOW_ENERGY */
-                       le_scan_params.type = BT_LE_ACTIVE_SCAN;
-                       le_scan_params.interval = BT_LE_SCAN_LOW_ENERGY_INTERVAL;
-                       le_scan_params.window = BT_LE_SCAN_LOW_ENERGY_WINDOW;
-                       is_le_set_scan_parameter = TRUE;
+                       _bt_set_scan_parameters(sender, &scanner->scan_params);
                }
-               _bt_set_scan_parameters(&le_scan_params);
 
                /* Enable scan filter if filter is exisiting */
                if (scanner->filter_list == NULL) {
@@ -2220,6 +2340,7 @@ int _bt_stop_le_scan(const char *sender)
        GSList *l;
        int ret;
 
+       bool rep;
        /* Check scanning is in progress or not */
        scanner = __bt_find_scanner_from_list(sender);
        if (scanner == NULL)
@@ -2240,6 +2361,16 @@ int _bt_stop_le_scan(const char *sender)
        if (next_scanning == TRUE) {
                int value = 0;
 
+               rep = _bt_pause_le_scan(scanner->scan_params);
+               if(rep) {
+                       if (is_le_scan_hold) {
+                               is_set_scan_parameter_in_progress = TRUE;
+                       }
+
+                       __bt_set_highest_scan_parameters();
+
+                       result = BLUETOOTH_ERROR_NONE;
+               }
                g_idle_add(__send_le_scan_reply, (void *)(intptr_t)value);
                result = BLUETOOTH_ERROR_NONE;
        } else {
@@ -2286,6 +2417,32 @@ int _bt_stop_le_scan(const char *sender)
        return result;
 }
 
+bool _bt_pause_le_scan(bluetooth_le_scan_params_t current_scan_params)
+{
+       int ret;
+
+       if (_bt_is_le_scanning() == FALSE) {
+               return true;
+       }
+
+       if(!(__bt_validateParams(current_scan_params))) {
+               ret = gattc_stop_le_discovery(g_gatt_client_id);
+               if (OAL_STATUS_SUCCESS == ret) {
+                       _bt_set_le_scan_stop_requested(TRUE);
+                       is_le_scan_hold = TRUE;
+               }
+               if (scan_filter_enabled == TRUE) {
+                       if (le_feature_info.vendor_filter == true) {
+                               ret = gattc_disable_scan_filter(0);
+                               if (ret != OAL_STATUS_SUCCESS)
+                                       BT_ERR("gattc_disable_scan_filter failed");
+                       }
+               }
+               return true;
+       }
+       return false;
+}
+
 void _bt_hold_le_scan(void)
 {
        int ret;
@@ -2330,7 +2487,7 @@ void _bt_restart_le_scan(void)
                le_scan_params.window = BT_LE_SCAN_LOW_ENERGY_WINDOW;
                is_le_set_scan_parameter = TRUE;
        }
-       _bt_set_scan_parameters(&le_scan_params);
+       _bt_set_scan_parameters(NULL, &le_scan_params);
 
        if (scan_filter_enabled == TRUE) {
                if (le_feature_info.vendor_filter == true) {
@@ -2381,6 +2538,8 @@ static void _bt_disable_all_scanner_status(void)
 void _bt_check_le_scanner_app_termination(const char *sender)
 {
        bt_adapter_le_scanner_t *scanner;
+       float highest_scan_duty = 0, scan_duty = 0;
+       bluetooth_le_scan_params_t *highest_scan_params;
 
        ret_if(NULL == sender);
 
@@ -2396,8 +2555,20 @@ void _bt_check_le_scanner_app_termination(const char *sender)
                        return;
        }
 
+       scan_duty = scanner->scan_params.window / scanner->scan_params.interval;
        scanner_list = g_slist_remove(scanner_list, scanner);
        __bt_free_le_scanner(scanner);
+
+       highest_scan_params = __bt_get_high_duty_scan_params();
+       highest_scan_duty = highest_scan_params->window / highest_scan_params->interval;
+
+       if (highest_scan_duty != scan_duty){
+               _bt_pause_le_scan(scanner->scan_params);
+               if (is_le_scan_hold)
+                       is_set_scan_parameter_in_progress = TRUE;
+
+               __bt_set_highest_scan_parameters();
+       }
 }
 
 int _bt_service_le_init(void)
index 1834e78fa16787e89c3425f3f87b71c1c640b9ff..30862b923ccba099fcb52fe3e4bb620ba708cd91 100644 (file)
@@ -3289,6 +3289,9 @@ int __bt_bluez_request(int function_name,
        }
        case BT_SET_SCAN_PARAMETERS: {
                bluetooth_le_scan_params_t scan_params;
+               bool rep;
+
+               sender = (char *)g_dbus_method_invocation_get_sender(context);
 
                __bt_service_get_parameters(in_param1, &scan_params,
                                sizeof(bluetooth_le_scan_params_t));
@@ -3297,7 +3300,13 @@ int __bt_bluez_request(int function_name,
                                scan_params.interval, scan_params.window,
                                scan_params.type);
 
-               result = _bt_prepare_scan_parameters(&scan_params, 0);
+               rep = _bt_pause_le_scan(scan_params);
+               if (rep) {
+                       result = _bt_set_scan_parameters(sender, &scan_params);
+               }
+               else {
+                       result = _bt_prepare_scan_parameters(&scan_params, 0);
+               }
                break;
        }
        case BT_SET_SCAN_TYPE: {
index a4a49545cfca710119ec303bbbcf1fe163c821eb..95fc932be974e4da9d3a9ced3a573e2b0cfb33b7 100644 (file)
@@ -89,9 +89,11 @@ int _bt_stop_le_scan(const char *sender);
 
 void _bt_hold_le_scan(void);
 
+bool _bt_pause_le_scan(bluetooth_le_scan_params_t current_scan_params);
+
 void _bt_restart_le_scan(void);
 
-int _bt_set_scan_parameters(bluetooth_le_scan_params_t *params);
+int _bt_set_scan_parameters(const char *sender, bluetooth_le_scan_params_t *params);
 
 int _bt_prepare_scan_parameters(bluetooth_le_scan_params_t *params, int scan_type);