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;
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 };
}
}
+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)
}
_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);
}
/*************************************** 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);
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);
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 */
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) {
GSList *l;
int ret;
+ bool rep;
/* Check scanning is in progress or not */
scanner = __bt_find_scanner_from_list(sender);
if (scanner == NULL)
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 {
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;
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) {
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);
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)