Add the status check logic for BT enable / disable method
[platform/core/connectivity/bluetooth-frwk.git] / bt-service / bt-service-adapter-le.c
index d6567b1..b7d9c49 100644 (file)
  */
 
 #include <stdio.h>
+#include <dbus/dbus.h>
 #include <gio/gio.h>
 #include <glib.h>
 #include <dlog.h>
 #include <string.h>
 #include <vconf.h>
 #include <syspopup_caller.h>
+#include <aul.h>
 
 #include "bt-internal-types.h"
 #include "bt-service-common.h"
@@ -39,7 +41,8 @@
 #define BT_ADV_FILTER_POLICY_DEFAULT   0x00
 #define BT_ADV_TYPE_DEFAULT    0x00
 #define BT_ADV_FILTER_POLICY_ALLOW_SCAN_CONN_WL_ONLY   0x03
-#define BT_ADV_MULTI_MAX   16
+#define BT_SCAN_INTERVAL_SPLIT 0.625
+
 
 typedef struct {
        int adv_inst_max;
@@ -77,9 +80,90 @@ GSList *scanner_list = NULL;
 static gboolean is_le_set_scan_parameter = FALSE;
 static gboolean is_le_scanning = FALSE;
 static gboolean scan_filter_enabled = FALSE;
-static bt_le_scan_type_t le_scan_type = BT_LE_PASSIVE_SCAN;
+static bt_le_scan_type_t le_scan_type = BT_LE_ACTIVE_SCAN;
+static bluetooth_le_scan_params_t le_scan_params = { BT_LE_ACTIVE_SCAN, 0, 0 };
+
+static GSList *gatt_client_senders = NULL;
+
+
+gboolean _bt_is_set_scan_parameter(void)
+{
+       return is_le_set_scan_parameter;
+}
 
-static void __bt_free_le_adv_slot(void)
+void _bt_init_gatt_client_senders(void)
+{
+       _bt_clear_request_list();
+}
+
+int _bt_insert_gatt_client_sender(char *sender)
+{
+       char *info;
+
+       retv_if(sender == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
+
+       info = g_strdup(sender);
+       retv_if(info == NULL, BLUETOOTH_ERROR_MEMORY_ALLOCATION);
+
+       gatt_client_senders = g_slist_append(gatt_client_senders, info);
+
+       BT_DBG("insert sender: %s", sender);
+
+       return BLUETOOTH_ERROR_NONE;
+}
+
+int _bt_delete_gatt_client_sender(char *sender)
+{
+       GSList *l;
+       char *info;
+
+       BT_DBG("remove sender: %s", sender);
+
+       for (l = gatt_client_senders; l != NULL; l = g_slist_next(l)) {
+               info = l->data;
+               if (info == NULL)
+                       continue;
+
+               if (g_strcmp0(info, sender) == 0) {
+                       BT_DBG("remove info");
+                       gatt_client_senders = g_slist_remove(gatt_client_senders, info);
+                       g_free(info);
+                       return BLUETOOTH_ERROR_NONE;
+               }
+       }
+
+       return BLUETOOTH_ERROR_NOT_FOUND;
+}
+
+void _bt_clear_gatt_client_senders(void)
+{
+       if (gatt_client_senders) {
+               g_slist_foreach(gatt_client_senders, (GFunc)g_free, NULL);
+               g_slist_free(gatt_client_senders);
+               gatt_client_senders = NULL;
+       }
+}
+#if 0
+static void __bt_send_foreach_event(gpointer data, gpointer user_data)
+{
+       char *sender = data;
+       GVariant *param = user_data;
+
+       _bt_send_event_to_dest(sender, BT_DEVICE_EVENT, BLUETOOTH_EVENT_GATT_CHAR_VAL_CHANGED,
+                                       param);
+}
+#endif
+void _bt_send_char_value_changed_event(void *param)
+{
+#if 0
+       g_slist_foreach(gatt_client_senders, __bt_send_foreach_event,
+                                       (gpointer)param);
+#else
+       _bt_send_event(BT_DEVICE_EVENT, BLUETOOTH_EVENT_GATT_CHAR_VAL_CHANGED, param);
+#endif
+}
+
+void __bt_free_le_adv_slot(void)
 {
        int i;
 
@@ -89,11 +173,56 @@ static void __bt_free_le_adv_slot(void)
        for (i = 0; i < le_feature_info.adv_inst_max; i++) {
                if (le_adv_slot[i].sender)
                        g_free(le_adv_slot[i].sender);
+               if (le_adv_slot[i].hold_timer_id > 0)
+                       g_source_remove(le_adv_slot[i].hold_timer_id);
        }
        g_free(le_adv_slot);
        le_adv_slot = NULL;
 }
 
+static void __bt_free_le_scanner(bt_adapter_le_scanner_t *scanner)
+{
+       g_free(scanner->sender);
+       g_slist_free_full(scanner->filter_list, g_free);
+       g_free(scanner);
+}
+
+static void __bt_free_le_scanner_all(void)
+{
+       g_slist_free_full(scanner_list, (GDestroyNotify)__bt_free_le_scanner);
+       scanner_list = NULL;
+
+       scan_filter_enabled = FALSE;
+       is_le_scanning = FALSE;
+       is_le_set_scan_parameter = FALSE;
+       le_scan_params.type = BT_LE_ACTIVE_SCAN;
+       le_scan_params.interval = 0;
+       le_scan_params.window = 0;
+}
+
+int _bt_le_set_max_packet_len(void)
+{
+       int result = BLUETOOTH_ERROR_NONE;
+       int tx_octets, tx_time;
+       bluetooth_le_read_maximum_data_length_t max_len = {0};
+
+       if (BLUETOOTH_ERROR_NONE != _bt_le_read_maximum_data_length(&max_len))
+               return BLUETOOTH_ERROR_INTERNAL;
+
+       if (max_len.max_tx_octets > BT_LE_TX_LEN_DEFAULT) {
+               tx_octets =  max_len.max_tx_octets > BT_LE_TX_LEN_MAX ?
+                               BT_LE_TX_LEN_MAX : max_len.max_tx_octets;
+               tx_time = BT_LE_TX_TIME_MAX;
+
+               result = _bt_le_write_host_suggested_default_data_length(tx_octets, tx_time);
+
+               BT_DBG("Wrote max packet size : result[%d], MAX[%d], set[%d]",
+                               result, max_len.max_tx_octets, tx_octets);
+       }
+
+       return result;
+}
+
 gboolean _bt_update_le_feature_support(const char *item, const char *value)
 {
        if (item == NULL || value == NULL)
@@ -107,7 +236,6 @@ gboolean _bt_update_le_feature_support(const char *item, const char *value)
 
                slot_num = atoi(value);
                retv_if(slot_num < 0, FALSE);
-               retv_if(slot_num > BT_ADV_MULTI_MAX, FALSE);
 
                if (slot_num != le_feature_info.adv_inst_max) {
                        __bt_free_le_adv_slot();
@@ -164,10 +292,10 @@ int __bt_get_available_adv_slot_id(const char *sender, int adv_handle, gboolean
                        return i;
        }
 
-       if (le_feature_info.adv_inst_max <= 2)
-               i = 0;
-       else if (le_feature_info.adv_inst_max > 2 && use_reserved_slot == TRUE)
+       if (le_feature_info.adv_inst_max <= 1)
                i = 0;
+       else if (use_reserved_slot == TRUE)
+               i = 1;
        else
                i = 2;
 
@@ -181,9 +309,6 @@ int __bt_get_available_adv_slot_id(const char *sender, int adv_handle, gboolean
 
 static void __bt_register_adv_slot_owner(const char *sender, int adv_handle, int slot_id)
 {
-       if (le_adv_slot == NULL)
-               return;
-
        if (le_adv_slot[slot_id].sender == NULL) {
                le_adv_slot[slot_id].sender = strdup(sender);
                le_adv_slot[slot_id].adv_handle = adv_handle;
@@ -192,9 +317,6 @@ static void __bt_register_adv_slot_owner(const char *sender, int adv_handle, int
 
 void _bt_unregister_adv_slot_owner(int slot_id)
 {
-       if (le_adv_slot == NULL)
-               return;
-
        if (le_adv_slot[slot_id].hold_timer_id > 0) {
                BT_INFO("Hold state adv is not unregistered");
                return;
@@ -223,9 +345,6 @@ int _bt_get_adv_slot_adv_handle(int slot_id)
 
 void _bt_set_advertising_status(int slot_id, gboolean mode)
 {
-       if (le_adv_slot == NULL)
-               return;
-
        le_adv_slot[slot_id].is_advertising = mode;
 }
 
@@ -234,6 +353,9 @@ gboolean _bt_is_advertising(void)
        gboolean status = FALSE;
        int i;
 
+       if (le_adv_slot == NULL)
+               return FALSE;
+
        for (i = 0; i < le_feature_info.adv_inst_max; i++) {
                if (le_adv_slot[i].is_advertising == TRUE)
                        status = TRUE;
@@ -242,11 +364,6 @@ gboolean _bt_is_advertising(void)
        return status;
 }
 
-gboolean _bt_is_multi_adv_supported(void)
-{
-       return (le_feature_info.adv_inst_max > 1) ? TRUE : FALSE;
-}
-
 void _bt_stop_advertising_by_terminated_process(const char* terminated_name)
 {
        int i;
@@ -320,6 +437,7 @@ int _bt_set_advertising(const char *sender, int adv_handle, gboolean enable, gbo
                                &error);
 
        if (error) {
+               BT_INFO("SetAdvertising %d, slot_id %d", enable, slot_id);
                BT_ERR("SetAdvertising Fail: %s", error->message);
                g_clear_error(&error);
                return BLUETOOTH_ERROR_INTERNAL;
@@ -329,7 +447,7 @@ int _bt_set_advertising(const char *sender, int adv_handle, gboolean enable, gbo
                __bt_register_adv_slot_owner(sender, adv_handle, slot_id);
 
        le_adv_slot[slot_id].is_advertising = enable;
-       BT_INFO_C("### Set advertising [%d]", enable);
+       BT_INFO_C("### Set advertising [%d], Slot id [%d]", enable, slot_id);
 
        if (ret)
                g_variant_unref(ret);
@@ -393,14 +511,18 @@ int _bt_set_custom_advertising(const char *sender, int adv_handle,
                        params->type == BLUETOOTH_ADV_NON_CONNECTABLE)
                return BLUETOOTH_ERROR_NOT_SUPPORT;
 
+       if (params->tx_power_level > 1 ||
+                       params->tx_power_level < -127)
+               return BLUETOOTH_ERROR_INVALID_PARAM;
+
        min = params->interval_min / BT_ADV_INTERVAL_SPLIT;
        max = params->interval_max / BT_ADV_INTERVAL_SPLIT;
 
        ret = g_dbus_proxy_call_sync(proxy, "SetAdvertisingParameters",
-                       g_variant_new("(uuuui)", min, max,
+                       g_variant_new("(uuuuii)", min, max,
                        params->filter_policy, params->type,
-                       slot_id), G_DBUS_CALL_FLAGS_NONE,
-                       -1, NULL, &error);
+                       params->tx_power_level, slot_id),
+                       G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
 
        if (error) {
                BT_ERR("SetAdvertisingParameters Fail: %s", error->message);
@@ -412,6 +534,7 @@ int _bt_set_custom_advertising(const char *sender, int adv_handle,
        adv_params.interval_max = params->interval_max;
        adv_params.filter_policy = params->filter_policy;
        adv_params.type = params->type;
+       adv_params.tx_power_level = params->tx_power_level;
 
        if (ret)
                g_variant_unref(ret);
@@ -433,7 +556,7 @@ int _bt_set_custom_advertising(const char *sender, int adv_handle,
                __bt_register_adv_slot_owner(sender, adv_handle, slot_id);
 
        le_adv_slot[slot_id].is_advertising = enable;
-       BT_INFO_C("### Set advertising [%d]", enable);
+       BT_INFO_C("### Set advertising [%d], Slot id [%d]", enable, slot_id);
        if (ret)
                g_variant_unref(ret);
 
@@ -764,6 +887,8 @@ int _bt_set_scan_parameters(bluetooth_le_scan_params_t *params)
        proxy = _bt_get_adapter_proxy();
        retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
 
+       BT_DBG("inteval %f, win %f, type %d", params->interval, params->window, params->type);
+
        if (params->interval < BT_LE_SCAN_INTERVAL_MIN || params->interval > BT_LE_SCAN_INTERVAL_MAX)
                return BLUETOOTH_ERROR_INVALID_PARAM;
 
@@ -773,8 +898,8 @@ 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_ADV_INTERVAL_SPLIT;
-       win = params->window / BT_ADV_INTERVAL_SPLIT;
+       itv = params->interval / BT_SCAN_INTERVAL_SPLIT;
+       win = params->window / BT_SCAN_INTERVAL_SPLIT;
 
        ret = g_dbus_proxy_call_sync(proxy, "SetScanParameters",
                        g_variant_new("(uuu)", params->type, itv, win),
@@ -793,7 +918,46 @@ int _bt_set_scan_parameters(bluetooth_le_scan_params_t *params)
 
        if (ret)
                g_variant_unref(ret);
-       BT_INFO("Set scan parameters");
+       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_NONE;
+}
+
+int _bt_prepare_scan_parameters(bluetooth_le_scan_params_t *params, int scan_type)
+{
+       if (_bt_adapter_get_status() != BT_ACTIVATED &&
+               _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
+               return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
+       }
+
+       if (params)
+               BT_DBG("inteval %f, win %f", params->interval, params->window);
+       else
+               BT_DBG("type %d", scan_type);
+
+       if (params) {
+               if (params->interval < BT_LE_SCAN_INTERVAL_MIN || params->interval > BT_LE_SCAN_INTERVAL_MAX)
+                       return BLUETOOTH_ERROR_INVALID_PARAM;
+
+               if (params->window < BT_LE_SCAN_WINDOW_MIN || params->window > BT_LE_SCAN_WINDOW_MAX)
+                       return BLUETOOTH_ERROR_INVALID_PARAM;
+
+               if (params->window > params->interval)
+                       return BLUETOOTH_ERROR_INVALID_PARAM;
+
+               le_scan_params.interval = params->interval;
+               le_scan_params.window = params->window;
+       } else {
+               le_scan_params.type = scan_type;
+               if (le_scan_params.interval == 0) {
+                       /* Set default scan interval same with BT_ADAPTER_LE_SCAN_MODE_LOW_ENERGY */
+                       le_scan_params.interval = 5120;
+                       le_scan_params.window = 512;
+               }
+       }
+
+       is_le_set_scan_parameter = TRUE;
+
        return BLUETOOTH_ERROR_NONE;
 }
 
@@ -811,7 +975,7 @@ bt_adapter_le_scanner_t* __bt_find_scanner_from_list(const char *sender)
        return NULL;
 }
 
-int __bt_get_available_scan_filter_slot_id(void)
+static int __bt_get_available_scan_filter_slot_id(void)
 {
        GSList *l;
        bt_adapter_le_scanner_t *scanner;
@@ -855,7 +1019,7 @@ gboolean _bt_is_scan_filter_supported(void)
        return FALSE;
 }
 
-int _bt_register_scan_filter(const char *sender, bluetooth_le_scan_filter_t *filter, int *slot_id)
+int _bt_register_scan_filter(const char *sender, bluetooth_le_scan_filter_t *filter)
 {
        GDBusProxy *proxy;
        GError *error = NULL;
@@ -869,9 +1033,10 @@ int _bt_register_scan_filter(const char *sender, bluetooth_le_scan_filter_t *fil
        bt_adapter_le_scanner_t *scanner = NULL;
        bluetooth_le_scan_filter_t *filter_data = NULL;
        int feature_selection = 0;
+       int slot_id;
 
-       *slot_id = __bt_get_available_scan_filter_slot_id();
-       if (*slot_id == -1)
+       slot_id = __bt_get_available_scan_filter_slot_id();
+       if (slot_id == -1)
                return BLUETOOTH_ERROR_NO_RESOURCES;
 
        proxy = _bt_get_adapter_proxy();
@@ -896,7 +1061,7 @@ int _bt_register_scan_filter(const char *sender, bluetooth_le_scan_filter_t *fil
                                        0,      // client_if
                                        0,      // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
                                        BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS,        // filter_type
-                                       *slot_id,       // filter_index
+                                       slot_id,        // filter_index
                                        0,      // company_id
                                        0,      // company_id_mask
                                        arr_uuid_param, // p_uuid
@@ -934,7 +1099,7 @@ int _bt_register_scan_filter(const char *sender, bluetooth_le_scan_filter_t *fil
                                        0,      // client_if
                                        0,      // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
                                        BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME,   // filter_type
-                                       *slot_id,       // filter_index
+                                       slot_id,        // filter_index
                                        0,      // company_id
                                        0,      // company_id_mask
                                        arr_uuid_param, // p_uuid
@@ -978,12 +1143,12 @@ int _bt_register_scan_filter(const char *sender, bluetooth_le_scan_filter_t *fil
                                        0,      // client_if
                                        0,      // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
                                        BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID,  // filter_type
-                                       *slot_id,       // filter_index
+                                       slot_id,        // filter_index
                                        0,      // company_id
                                        0,      // company_id_mask
                                        arr_uuid_param, // p_uuid
                                        arr_uuid_mask_param,    // p_uuid_mask
-                                       NULL,   // string
+                                       "",     // string
                                        0,      // address_type
                                        arr_data_param, // p_data
                                        arr_data_mask_param);
@@ -1001,8 +1166,6 @@ int _bt_register_scan_filter(const char *sender, bluetooth_le_scan_filter_t *fil
 
                g_array_free(arr_uuid, TRUE);
                g_array_free(arr_uuid_mask, TRUE);
-               g_array_free(arr_data, TRUE);
-               g_array_free(arr_data_mask, TRUE);
        }
 
        if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID) {
@@ -1027,12 +1190,12 @@ int _bt_register_scan_filter(const char *sender, bluetooth_le_scan_filter_t *fil
                                        0,      // client_if
                                        0,      // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
                                        BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID,     // filter_type
-                                       *slot_id,       // filter_index
+                                       slot_id,        // filter_index
                                        0,      // company_id
                                        0,      // company_id_mask
                                        arr_uuid_param, // p_uuid
                                        arr_uuid_mask_param,    // p_uuid_mask
-                                       NULL,   // string
+                                       "",     // string
                                        0,      // address_type
                                        arr_data_param, // p_data
                                        arr_data_mask_param);
@@ -1074,12 +1237,12 @@ int _bt_register_scan_filter(const char *sender, bluetooth_le_scan_filter_t *fil
                                        0,      // client_if
                                        0,      // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
                                        BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA,  // filter_type
-                                       *slot_id,       // filter_index
+                                       slot_id,        // filter_index
                                        0,      // company_id
                                        0,      // company_id_mask
                                        arr_uuid_param, // p_uuid
                                        arr_uuid_mask_param,    // p_uuid_mask
-                                       NULL,   // string
+                                       "",     // string
                                        0,      // address_type
                                        arr_data_param, // p_data
                                        arr_data_mask_param);
@@ -1121,12 +1284,12 @@ int _bt_register_scan_filter(const char *sender, bluetooth_le_scan_filter_t *fil
                                        0,      // client_if
                                        0,      // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
                                        BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA,     // filter_type
-                                       *slot_id,       // filter_index
+                                       slot_id,        // filter_index
                                        filter->manufacturer_id,        // company_id
                                        0xFFFF, // company_id_mask
                                        arr_uuid_param, // p_uuid
                                        arr_uuid_mask_param,    // p_uuid_mask
-                                       NULL,   // string
+                                       "",     // string
                                        0,      // address_type
                                        arr_data_param, // p_data
                                        arr_data_mask_param);
@@ -1151,7 +1314,7 @@ int _bt_register_scan_filter(const char *sender, bluetooth_le_scan_filter_t *fil
        param = g_variant_new("(iiiiiiiiiiii)",
                                0,      // client_if
                                0,      // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
-                               *slot_id,       // filter_index
+                               slot_id,        // filter_index
                                feature_selection,      // feat_seln
                                0,      // list_logic_type (OR - 0x00, AND - 0x01)
                                1,      // filt_logic_type (OR - 0x00, AND - 0x01)
@@ -1181,7 +1344,7 @@ int _bt_register_scan_filter(const char *sender, bluetooth_le_scan_filter_t *fil
        if (scanner) {
                filter_data = g_malloc0(sizeof(bluetooth_le_scan_filter_t));
                memcpy(filter_data, filter, sizeof(bluetooth_le_scan_filter_t));
-               filter_data->slot_id = *slot_id;
+               filter_data->slot_id = slot_id;
 
                scanner->filter_list = g_slist_append(scanner->filter_list, filter_data);
        }
@@ -1191,55 +1354,6 @@ int _bt_register_scan_filter(const char *sender, bluetooth_le_scan_filter_t *fil
        return BLUETOOTH_ERROR_NONE;
 }
 
-int _bt_unregister_scan_filter(const char *sender, int slot_id)
-{
-       GDBusProxy *proxy;
-       GError *error = NULL;
-       GVariant *ret;
-       bt_adapter_le_scanner_t *scanner = NULL;
-       bluetooth_le_scan_filter_t *filter_data = NULL;
-       GSList *l;
-       gboolean is_slot_id_found = FALSE;
-
-       scanner = __bt_find_scanner_from_list(sender);
-       if (scanner == NULL) {
-               BT_ERR("There is NO available scanner.");
-               return BLUETOOTH_ERROR_NOT_FOUND;
-       }
-
-       for (l = scanner->filter_list; l != NULL; l = g_slist_next(l)) {
-               filter_data = l->data;
-               if (filter_data->slot_id == slot_id) {
-                       is_slot_id_found = TRUE;
-                       break;
-               }
-       }
-       if (is_slot_id_found == FALSE) {
-               BT_ERR("There is NO registered slot.");
-               return BLUETOOTH_ERROR_NOT_FOUND;
-       }
-
-       proxy = _bt_get_adapter_proxy();
-       retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
-
-       ret = g_dbus_proxy_call_sync(proxy, "scan_filter_clear",
-                               g_variant_new("(ii)", 0, slot_id),
-                               G_DBUS_CALL_FLAGS_NONE,
-                               -1, NULL, &error);
-
-       if (error) {
-               BT_ERR("scan_filter_clear Fail: %s", error->message);
-               g_clear_error(&error);
-       }
-
-       scanner->filter_list = g_slist_remove(scanner->filter_list, filter_data);
-       g_free(filter_data);
-
-       if (ret)
-               g_variant_unref(ret);
-       return BLUETOOTH_ERROR_NONE;
-}
-
 int _bt_unregister_all_scan_filters(const char *sender)
 {
        GDBusProxy *proxy;
@@ -1309,7 +1423,7 @@ int _bt_start_le_scan(const char *sender)
                                                G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
 
                                if (error) {
-                                       BT_ERR("scan_filter_clear Fail: %s", error->message);
+                                       BT_ERR("scan_filter_enable Fail: %s", error->message);
                                        g_clear_error(&error);
                                }
 
@@ -1329,10 +1443,11 @@ int _bt_start_le_scan(const char *sender)
                        /* Set default scan parameter same with BT_ADAPTER_LE_SCAN_MODE_LOW_ENERGY */
                        bluetooth_le_scan_params_t scan_params;
                        scan_params.type = BT_LE_ACTIVE_SCAN;
-                       scan_params.interval = 5000;
-                       scan_params.window = 500;
+                       scan_params.interval = 5120;
+                       scan_params.window = 512;
                        _bt_set_scan_parameters(&scan_params);
-               }
+               } else
+                       _bt_set_scan_parameters(&le_scan_params);
 
                if (scanner->filter_list == NULL) {
                        BT_INFO("Start LE Full Scan");
@@ -1343,7 +1458,7 @@ int _bt_start_le_scan(const char *sender)
                                        G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
 
                        if (error) {
-                               BT_ERR("scan_filter_clear Fail: %s", error->message);
+                               BT_ERR("scan_filter_enable Fail: %s", error->message);
                                g_clear_error(&error);
                        }
 
@@ -1382,7 +1497,10 @@ int _bt_stop_le_scan(const char *sender)
        if (scanner == NULL || scanner->is_scanning == FALSE)
                return BLUETOOTH_ERROR_NOT_IN_OPERATION;
 
-       scanner->is_scanning = FALSE;
+       _bt_unregister_all_scan_filters(sender);
+
+       scanner_list = g_slist_remove(scanner_list, scanner);
+       __bt_free_le_scanner(scanner);
 
        for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
                scanner = l->data;
@@ -1404,7 +1522,7 @@ int _bt_stop_le_scan(const char *sender)
                                        -1, NULL, &error);
 
                        if (error) {
-                               BT_ERR("scan_filter_clear Fail: %s", error->message);
+                               BT_ERR("scan_filter_enable Fail: %s", error->message);
                                g_clear_error(&error);
                        }
 
@@ -1413,6 +1531,7 @@ int _bt_stop_le_scan(const char *sender)
                        BT_INFO("Enable LE Scan Filter");
                        scan_filter_enabled = TRUE;
                }
+               BT_INFO("next_scanning exists. Keep the LE scanning");
                return BLUETOOTH_ERROR_NONE;
        } else {
                if (scan_filter_enabled == TRUE) {
@@ -1422,7 +1541,7 @@ int _bt_stop_le_scan(const char *sender)
                                        -1, NULL, &error);
 
                        if (error) {
-                               BT_ERR("scan_filter_clear Fail: %s", error->message);
+                               BT_ERR("scan_filter_enable Fail: %s", error->message);
                                g_clear_error(&error);
                        }
 
@@ -1437,6 +1556,11 @@ int _bt_stop_le_scan(const char *sender)
        ret = g_dbus_proxy_call_sync(proxy, "StopLEDiscovery",
                                NULL, G_DBUS_CALL_FLAGS_NONE,
                                -1, NULL, &error);
+       if (error) {
+               BT_ERR("StopLEDiscovery Fail: %s", error->message);
+               g_clear_error(&error);
+       }
+
        if (ret == NULL) {
                BT_ERR("LE Scan stop failed");
                return BLUETOOTH_ERROR_INTERNAL;
@@ -1444,6 +1568,9 @@ int _bt_stop_le_scan(const char *sender)
 
        scan_filter_enabled = FALSE;
        is_le_set_scan_parameter = FALSE;
+       le_scan_params.type = BT_LE_ACTIVE_SCAN;
+       le_scan_params.interval = 0;
+       le_scan_params.window = 0;
        if (ret)
                g_variant_unref(ret);
        return BLUETOOTH_ERROR_NONE;
@@ -1460,28 +1587,9 @@ void _bt_disable_all_scanner_status(void)
        }
 }
 
-static void __bt_free_le_scanner(void)
-{
-       GSList *l;
-       bt_adapter_le_scanner_t *scanner;
-
-       for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
-               scanner = l->data;
-               g_free(scanner->sender);
-               g_slist_free_full(scanner->filter_list, g_free);
-               g_free(scanner);
-       }
-
-       g_slist_free(scanner_list);
-       scanner_list = NULL;
-
-       scan_filter_enabled = FALSE;
-       is_le_scanning = FALSE;
-       is_le_set_scan_parameter = FALSE;
-}
-
 void _bt_set_le_scan_status(gboolean mode)
 {
+       BT_DBG("set is_le_scanning : %d -> %d", is_le_scanning, mode);
        is_le_scanning = mode;
 }
 
@@ -1836,10 +1944,8 @@ void _bt_send_scan_result_event(const bt_remote_le_dev_info_t *le_dev_info,
        int scan_data_len = 0;
 
        ret_if(le_dev_info == NULL);
-       if (_bt_get_le_scan_type() == BT_LE_ACTIVE_SCAN)
-               ret_if(adv_info == NULL);
 
-       if (_bt_get_le_scan_type() == BT_LE_PASSIVE_SCAN) {
+       if (adv_info == NULL) { /* Not received scan response data within 1 sec */
                adv_data = le_dev_info->adv_data;
                adv_data_len = le_dev_info->adv_data_len;
                scan_data = le_dev_info->adv_data;
@@ -1876,8 +1982,42 @@ void _bt_send_scan_result_event(const bt_remote_le_dev_info_t *le_dev_info,
                                        scan_data_len,
                                        scan_data_param);
 
+#if 0
                _bt_send_event_to_dest(scanner->sender, BT_LE_ADAPTER_EVENT,
                                BLUETOOTH_EVENT_REMOTE_LE_DEVICE_FOUND, param);
+#else
+               _bt_send_event(BT_LE_ADAPTER_EVENT, BLUETOOTH_EVENT_REMOTE_LE_DEVICE_FOUND, param);
+#endif
+       }
+}
+
+void _bt_send_ibeacon_scan_result_event(const bt_remote_ibeacon_dev_info_t *ibeacon_dev_info)
+{
+       int result = BLUETOOTH_ERROR_NONE;
+       GSList *l;
+       GVariant *param;
+       bt_adapter_le_scanner_t *scanner = NULL;
+
+       ret_if(ibeacon_dev_info == NULL);
+       BT_DBG("_bt_send_ibeacon_scan_result_event");
+
+       for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
+               scanner = l->data;
+               if (scanner->is_scanning == FALSE)
+                       continue;
+
+               param = g_variant_new("(isnnnsnnn)",
+                                       result,
+                                       ibeacon_dev_info->address,
+                                       ibeacon_dev_info->addr_type,
+                                       ibeacon_dev_info->company_id,
+                                       ibeacon_dev_info->ibeacon_type,
+                                       ibeacon_dev_info->uuid,
+                                       ibeacon_dev_info->major_id,
+                                       ibeacon_dev_info->minor_id,
+                                       ibeacon_dev_info->measured_power);
+
+               _bt_send_event(BT_LE_ADAPTER_EVENT, BLUETOOTH_EVENT_REMOTE_IBEACON_DEVICE_FOUND, param);
        }
 }
 
@@ -2223,5 +2363,5 @@ int _bt_service_adapter_le_init(void)
 void _bt_service_adapter_le_deinit(void)
 {
        __bt_free_le_adv_slot();
-       __bt_free_le_scanner();
+       __bt_free_le_scanner_all();
 }