Resolve the LE advertising fail after slot exhaustion
[platform/core/connectivity/bluetooth-frwk.git] / bt-oal / bluez_hal / src / bt-hal-adapter-le.c
index a901c7a..27b56fb 100644 (file)
 #include "bt-hal-gatt-server.h"
 
 typedef struct {
-        int adv_inst_max;
-        int rpa_offloading;
-        int max_filter;
+       int adv_inst_max;
+       int rpa_offloading;
+       int max_filter;
+       int le_2m_phy;
+       int le_coded_phy;
 } bt_adapter_le_feature_info_t;
 
 typedef struct {
        int initialized;
        gboolean is_multi_adv; /* To be removed once we complete descope Legacy Adv */
-        int adv_handle;
-        gboolean is_advertising;
-        guint hold_timer_id;
+       int adv_handle;
+       gboolean is_advertising;
+       guint hold_timer_id;
        bt_uuid_t app_uuid;
 } bt_adapter_le_adv_slot_t;
 
@@ -68,9 +70,9 @@ static bt_adapter_le_adv_slot_t *le_adv_slot = NULL;
 
 typedef struct {
        uint8_t event;
-        int server_if;
-        uint8_t status;
-        uint8_t data[31];
+       int server_if;
+       uint8_t status;
+       uint8_t data[31];
 } bt_hal_adv_event_data_t;
 
 /* Macros */
@@ -116,6 +118,37 @@ int _bt_hal_le_disable(void)
 {
        return _bt_hal_dbus_disable_le();
 }
+
+int _bt_hal_set_le_static_random_address(uint8_t enable)
+{
+       DBG("+");
+       GError *error = NULL;
+       GVariant *ret;
+       GDBusProxy *proxy;
+
+       proxy = _bt_hal_get_adapter_proxy();
+       if (proxy == NULL)
+               return BT_STATUS_FAIL;
+
+       ret = g_dbus_proxy_call_sync(proxy, "SetLeStaticRandomAddress",
+                       g_variant_new("(b)", (enable ? TRUE : FALSE)),
+                       G_DBUS_CALL_FLAGS_NONE,
+                       -1,
+                       NULL,
+                       &error);
+
+       if (error) {
+               ERR("Set static address Fail: %s", error->message);
+               g_clear_error(&error);
+               return BT_STATUS_FAIL;
+       }
+
+       INFO("Set le static address [%d]", enable);
+       if (ret)
+               g_variant_unref(ret);
+
+       return BT_STATUS_SUCCESS;
+}
 #endif
 
 static void __bt_hal_free_le_adv_slot(void)
@@ -125,9 +158,9 @@ static void __bt_hal_free_le_adv_slot(void)
        if (le_adv_slot == NULL)
                return;
 
-       for (i = 0; i < le_feature_info.adv_inst_max; i++) {
+       for (i = 0; i < le_feature_info.adv_inst_max; i++)
                memset(&le_adv_slot[i], 0x00, sizeof(bt_adapter_le_adv_slot_t));
-       }
+
        g_free(le_adv_slot);
        le_adv_slot = NULL;
 }
@@ -155,38 +188,51 @@ gboolean _bt_hal_is_advertising_in_slot(int slot)
 
 void _bt_hal_set_advertising_status(int slot_id, gboolean mode)
 {
-
-       DBG("Advertising enabled [%s] slot [%d]",  mode? "TRUE": "FALSE", slot_id);
        bt_hal_adv_event_data_t *event;
+       int adv_slot_id = slot_id;
+       int server_if = 0;
+
+       server_if = bt_hal_gatts_get_server_if(slot_id);
+
+       DBG("Advertising enabled [%s] server_slot [%d] server_if[%d]",  mode ? "TRUE" : "FALSE", slot_id, server_if);
 
        if (le_adv_slot == NULL)
                return;
 
-       le_adv_slot[slot_id].is_advertising = mode;
+       le_adv_slot[adv_slot_id].is_advertising = mode;
 
        event = g_malloc0(sizeof(bt_hal_adv_event_data_t));
-       event->event = mode? BT_HAL_MULTI_ADV_ENB_EVT: BT_HAL_MULTI_ADV_DISABLE_EVT;
-       event->server_if = slot_id;
+       event->event = mode ? BT_HAL_MULTI_ADV_ENB_EVT : BT_HAL_MULTI_ADV_DISABLE_EVT;
+
+       event->server_if = server_if;
        event->status = BT_STATUS_SUCCESS;
        /* To be removed later when we completely descope Legacy Adv concept */
-       DBG("Is multi ? [%d]", le_adv_slot[slot_id].is_multi_adv);
-       if (le_adv_slot[slot_id].is_multi_adv == FALSE)
+
+       DBG("adv_slot_id[%d] Is multi ? [%d]", adv_slot_id, le_adv_slot[adv_slot_id].is_multi_adv);
+       if (le_adv_slot[adv_slot_id].is_multi_adv == FALSE)
                event->event = BT_HAL_LEGACY_ADV_STATUS;
 
+       if (mode == false ) {
+               DBG("release the adv_slot");
+               bt_hal_gatts_release_adv_slot(server_if);
+       }
+
        __bt_hal_adv_event_cb((gpointer)event);
 }
 
 gboolean _bt_hal_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;
+                       return TRUE;
        }
 
-       return status;
+       return FALSE;
 }
 
 int _bt_hal_le_init(void)
@@ -198,7 +244,9 @@ void _bt_hal_le_deinit(void)
 {
        __bt_hal_free_le_adv_slot();
 }
-gboolean _bt_hal_update_le_feature_support(const char *item, const char *value)
+
+gboolean _bt_hal_update_le_feature_support(const char *item, const char *value,
+                       bt_local_le_features_t *le_features)
 {
        if (item == NULL || value == NULL)
                return FALSE;
@@ -209,6 +257,7 @@ gboolean _bt_hal_update_le_feature_support(const char *item, const char *value)
                int slot_num;
 
                slot_num = atoi(value);
+               INFO("slot_num:[%d]", slot_num);
                if (slot_num < 0) {
                        ERR("ERR:Advertising MAX instance [%d]", slot_num);
                        return FALSE;
@@ -220,12 +269,47 @@ gboolean _bt_hal_update_le_feature_support(const char *item, const char *value)
                        INFO("Advertising instance max : %d", le_feature_info.adv_inst_max);
                        le_adv_slot = g_malloc0(sizeof(bt_adapter_le_adv_slot_t) * le_feature_info.adv_inst_max);
                }
+
+               INFO("Advertising instance max: [%d]", le_feature_info.adv_inst_max);
+               /* Fill LE feature bytes */
+               le_features->max_adv_instance = atoi(value);
+
        } else if (g_strcmp0(item, "rpa_offloading") == 0) {
                le_feature_info.rpa_offloading = atoi(value);
                INFO("RPA offloading : %d", le_feature_info.rpa_offloading);
+
+               /* Fill LE feature bytes */
+               le_features->rpa_offload_supported = atoi(value);
+
        } else if (g_strcmp0(item, "max_filter") == 0) {
                le_feature_info.max_filter = atoi(value);
                INFO("BLE Scan max filter : %d", le_feature_info.max_filter);
+
+               /* Fill LE feature bytes */
+               le_features->max_adv_filter_supported = atoi(value);
+
+       } else if (g_strcmp0(item, "2m_phy") == 0) {
+               if (g_strcmp0(value, "true") == 0) {
+                       le_feature_info.le_2m_phy = TRUE;
+                       /* Fill LE feature bytes */
+                       le_features->le_2m_phy_supported = 0x1;
+               } else {
+                       le_feature_info.le_2m_phy = FALSE;
+                       /* Fill LE feature bytes */
+                       le_features->le_2m_phy_supported = 0x0;
+               }
+               INFO("2M PHY Supported [%s]",  le_feature_info.le_2m_phy ? "TRUE" : "FALSE");
+       } else if (g_strcmp0(item, "coded_phy") == 0) {
+               if (g_strcmp0(value, "true") == 0) {
+                       le_feature_info.le_coded_phy = TRUE;
+                       /* Fill LE feature bytes */
+                       le_features->le_coded_phy_supported = 0x1;
+               } else {
+                       le_feature_info.le_coded_phy = FALSE;
+                       /* Fill LE feature bytes */
+                       le_features->le_coded_phy_supported = 0x0;
+               }
+               INFO("CODED PHY Supported [%s]",  le_feature_info.le_coded_phy ? "TRUE" : "FALSE");
        } else {
                DBG("No registered item");
                return FALSE;
@@ -241,7 +325,7 @@ void _bt_hal_free_server_slot(int slot_id)
        memset(&le_adv_slot[slot_id], 0x00, sizeof(bt_adapter_le_adv_slot_t));
 }
 
-int _bt_hal_get_available_adv_slot_id(bt_uuid_t *uuid)
+int _bt_hal_get_available_adv_slot_id(bt_uuid_t *uuid, gboolean use_reserved_slot)
 {
        int i;
 
@@ -261,6 +345,14 @@ int _bt_hal_get_available_adv_slot_id(bt_uuid_t *uuid)
                }
        }
 
+       /* We should consider 'use_reverved_slot' in later */
+       if (le_feature_info.adv_inst_max <= 1)
+               i = 0;
+       else if (use_reserved_slot == TRUE)
+               i = 1;
+       else
+               i = 2;
+
        for (i = 0; i < le_feature_info.adv_inst_max; i++) {
                if (le_adv_slot[i].initialized == 0) {
                        DBG("Slot to be allocated [%d] UUID to be registered [%s]",
@@ -401,7 +493,7 @@ static void __bt_hal_parse_uuid(int len, char *src, uint8_t *dest, int *length,
                                dest[index+1] = 0x06; /* AD Type */
                        memcpy(&(dest[index + 2]), &src[12], byte_len);
                        /* Update current type */
-                        prev_byte_len = byte_len;
+                       prev_byte_len = byte_len;
                        *length += 18;
                        break;
                }
@@ -420,19 +512,19 @@ static void __bt_hal_parse_uuid(int len, char *src, uint8_t *dest, int *length,
 
 static gboolean __bt_hal_is_factory_test_mode(void)
 {
-        int mode = 0;
+       int mode = 0;
 
-        if (vconf_get_bool(VCONFKEY_BT_DUT_MODE, &mode)) {
-                ERR("Get the DUT Mode fail");
-                return TRUE;
-        }
+       if (vconf_get_bool(VCONFKEY_BT_DUT_MODE, &mode)) {
+               ERR("Get the DUT Mode fail");
+               return TRUE;
+       }
 
-        if (mode != FALSE) {
-                INFO("DUT Test Mode !!");
-                return TRUE;
-        }
+       if (mode != FALSE) {
+               INFO("DUT Test Mode !!");
+               return TRUE;
+       }
 
-        return FALSE;
+       return FALSE;
 }
 
 static gboolean __bt_hal_adv_event_cb(gpointer param)
@@ -448,7 +540,7 @@ static gboolean __bt_hal_adv_event_cb(gpointer param)
                return FALSE;
        }
 
-       switch(event->event) {
+       switch (event->event) {
        case BT_HAL_MULTI_ADV_ENB_EVT: {
                INFO("BLE Advertising enabled slot [%d]", event->server_if);
                struct hal_ev_multi_adv_enable ev;
@@ -511,7 +603,7 @@ static gboolean __bt_hal_adv_event_cb(gpointer param)
        return FALSE;
 }
 
-int _bt_hal_enable_advertising(int server_if, bool enable, bool is_multi_adv)
+int _bt_hal_enable_advertising(int server_if, int adv_slot_id, bool enable, bool is_multi_adv)
 {
        DBG("+");
        GError *error = NULL;
@@ -522,21 +614,21 @@ int _bt_hal_enable_advertising(int server_if, bool enable, bool is_multi_adv)
        if (proxy == NULL)
                return BT_STATUS_FAIL;
 
-       if (le_adv_slot[server_if].is_advertising == TRUE && enable == TRUE)
+       if (le_adv_slot[adv_slot_id].is_advertising == TRUE && enable == TRUE)
                return BT_STATUS_BUSY;
 
-       if (le_adv_slot[server_if].initialized == TRUE &&
-                       le_adv_slot[server_if].is_advertising == FALSE &&
+       if (le_adv_slot[adv_slot_id].initialized == TRUE &&
+                       le_adv_slot[adv_slot_id].is_advertising == FALSE &&
                        enable == FALSE)
                return BT_STATUS_DONE;
 
-       if (le_adv_slot[server_if].hold_timer_id > 0) {
-               g_source_remove(le_adv_slot[server_if].hold_timer_id);
-               le_adv_slot[server_if].hold_timer_id = 0;
+       if (le_adv_slot[adv_slot_id].hold_timer_id > 0) {
+               g_source_remove(le_adv_slot[adv_slot_id].hold_timer_id);
+               le_adv_slot[adv_slot_id].hold_timer_id = 0;
        }
 
        ret = g_dbus_proxy_call_sync(proxy, "SetAdvertising",
-                       g_variant_new("(bi)", enable, server_if),
+                       g_variant_new("(bi)", enable, adv_slot_id),
                        G_DBUS_CALL_FLAGS_NONE,
                        -1,
                        NULL,
@@ -548,71 +640,75 @@ int _bt_hal_enable_advertising(int server_if, bool enable, bool is_multi_adv)
                return BT_STATUS_FAIL;
        }
 
-       INFO("Enable advertising [%d] SLot Id [%d] Is Multi? [%d]", enable, server_if, is_multi_adv);
+       INFO("Enable advertising [%d] SLot Id [%d] gatt_server [%d] Is Multi? [%d]",
+                               enable, adv_slot_id, server_if, is_multi_adv);
        if (ret)
                g_variant_unref(ret);
 
-       le_adv_slot[server_if].is_multi_adv = is_multi_adv;
-       le_adv_slot[server_if].is_advertising = enable;
+       le_adv_slot[adv_slot_id].is_multi_adv = is_multi_adv;
+       le_adv_slot[adv_slot_id].is_advertising = enable;
        return BT_STATUS_SUCCESS;
 }
 
 int _bt_hal_set_advertising_params(int server_if, int min_interval,
-               int max_interval,int adv_type,
-                int chnl_map, int tx_power, int timeout_s)
+               int max_interval, int adv_type,
+               int chnl_map, int tx_power, int timeout_s)
 {
        DBG("+");
        GDBusProxy *proxy;
-        GVariant *ret;
-        GError *error = NULL;
-        guint32 min = 0;
-        guint32 max = 0;
+       GVariant *ret;
+       GError *error = NULL;
+       guint32 min = 0;
+       guint32 max = 0;
        bt_hal_adv_event_data_t *event;
+       int slot_id = 0;
 
 
        proxy = _bt_hal_get_adapter_proxy();
-        if (proxy == NULL)
+       if (proxy == NULL)
                return BT_STATUS_FAIL;
 
        if (min_interval > max_interval ||
-                        min_interval < BT_HAL_ADV_INTERVAL_MIN ||
-                        max_interval > BT_HAL_ADV_INTERVAL_MAX)
+                       min_interval < BT_HAL_ADV_INTERVAL_MIN ||
+                       max_interval > BT_HAL_ADV_INTERVAL_MAX)
                return BT_STATUS_PARM_INVALID;
 
 
        if (adv_type  == BT_HAL_ADV_CONNECTABLE_DIRECT_HIGH ||
-                        adv_type == BT_HAL_ADV_CONNECTABLE_DIRECT_LOW ||
-                        adv_type == BT_HAL_ADV_NON_CONNECTABLE)
-                return BT_STATUS_UNSUPPORTED;
+                       adv_type == BT_HAL_ADV_CONNECTABLE_DIRECT_LOW ||
+                       adv_type == BT_HAL_ADV_NON_CONNECTABLE)
+               return BT_STATUS_UNSUPPORTED;
 
 
        min = min_interval / BT_HAL_ADV_INTERVAL_SPLIT;
-        max = max_interval / BT_HAL_ADV_INTERVAL_SPLIT;
+       max = max_interval / BT_HAL_ADV_INTERVAL_SPLIT;
+
+       slot_id = bt_hal_gatts_allocate_adv_slot_by_server_if(server_if);
 
        ret = g_dbus_proxy_call_sync(proxy, "SetAdvertisingParameters",
-                        g_variant_new("(uuuui)", min, max,
-                        BT_HAL_ADV_FILTER_POLICY_DEFAULT, adv_type,
-                        server_if), G_DBUS_CALL_FLAGS_NONE,
-                        -1, NULL, &error);
+                       g_variant_new("(uuuuii)", min, max,
+                       BT_HAL_ADV_FILTER_POLICY_DEFAULT, adv_type,
+                       tx_power, slot_id), G_DBUS_CALL_FLAGS_NONE,
+                       -1, NULL, &error);
        if (error) {
-                ERR("SetAdvertisingParameters Fail: %s", error->message);
-                g_clear_error(&error);
+               ERR("SetAdvertisingParameters Fail: %s", error->message);
+               g_clear_error(&error);
                return BT_STATUS_FAIL;
-        }
+       }
 
        INFO("Set advertising data");
-        if (ret)
-                g_variant_unref(ret);
+       if (ret)
+               g_variant_unref(ret);
 
        /*
-         * As we need to provide async callback to user from HAL, simply schedule a
-         * callback method which will carry actual result
-         */
+        * As we need to provide async callback to user from HAL, simply schedule a
+        * callback method which will carry actual result
+        */
        event = g_malloc0(sizeof(bt_hal_adv_event_data_t));
        event->event  = BT_HAL_MULTI_ADV_UPDATE_EVT;
        event->server_if = server_if;
        event->status = BT_STATUS_SUCCESS;
-        g_idle_add(__bt_hal_adv_event_cb, (gpointer)event);
+       g_idle_add(__bt_hal_adv_event_cb, (gpointer)event);
 
        return BT_STATUS_SUCCESS;
 }
@@ -624,25 +720,28 @@ int _bt_hal_set_advertising_data(btgatt_adv_param_setup_t adv_param_setup)
        uint8_t adv_data[31];
        int index = 0;
        GDBusProxy *proxy;
-        GError *error = NULL;
-        GVariant *ret = NULL;
-        GVariant *temp = NULL;
-        GVariantBuilder *builder;
+       GError *error = NULL;
+       GVariant *ret = NULL;
+       GVariant *temp = NULL;
+       GVariantBuilder *builder;
        bt_hal_adv_event_data_t *event;
        int length = 0;
-        int i;
+       int i;
+       int slot_id = 0;
 
        /* Parse data according to Bluez Interface */
        if (__bt_hal_is_factory_test_mode()) {
-                ERR("Unable to set advertising data in factory binary !!");
-                return BT_STATUS_UNSUPPORTED;
-        }
+               ERR("Unable to set advertising data in factory binary !!");
+               return BT_STATUS_UNSUPPORTED;
+       }
 
        /* TODO: Check adapter and LE adapter status */
        proxy = _bt_hal_get_adapter_proxy();
-        if (proxy == NULL)
+       if (proxy == NULL)
                return BT_STATUS_FAIL;
 
+       slot_id = bt_hal_gatts_allocate_adv_slot_by_server_if(adv_param_setup.server_if);
+
        memset(&adv_data, 0, 31);
 
        /* Service UUID */
@@ -715,52 +814,52 @@ int _bt_hal_set_advertising_data(btgatt_adv_param_setup_t adv_param_setup)
 
        /* Create Builder */
        builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
-        for (i = 0; i < length; i++)
-                g_variant_builder_add(builder, "y", adv_data[i]);
+       for (i = 0; i < length; i++)
+               g_variant_builder_add(builder, "y", adv_data[i]);
 
-        temp = g_variant_new("ay", builder);
-        g_variant_builder_unref(builder);
+       temp = g_variant_new("ay", builder);
+       g_variant_builder_unref(builder);
 
-        DBG("####Adv data length [%d] Index [%d]", length, index);
-        for (i = 0; i < length; i++)
-                DBG("##Data[%d] [0x%x]", i, adv_data[i]);
+       DBG("####Adv data length [%d] Index [%d]", length, index);
+       for (i = 0; i < length; i++)
+               DBG("##Data[%d] [0x%x]", i, adv_data[i]);
 
        if (adv_param_setup.set_scan_rsp == 0) {
                /* Set Advertising data to stack */
                ret = g_dbus_proxy_call_sync(proxy, "SetAdvertisingData",
-                               g_variant_new("(@ayi)", temp, adv_param_setup.server_if),
+                               g_variant_new("(@ayi)", temp, slot_id),
                                G_DBUS_CALL_FLAGS_NONE,
                                -1, NULL, &error);
        } else {
                /* Set Scan response data to stack */
                ret = g_dbus_proxy_call_sync(proxy, "SetScanRespData",
-                               g_variant_new("(@ayi)", temp, adv_param_setup.server_if),
+                               g_variant_new("(@ayi)", temp, slot_id),
                                G_DBUS_CALL_FLAGS_NONE,
                                -1, NULL, &error);
        }
 
-        if (error) {
-                ERR("SetAdvertisingData Fail: %s", error->message);
-                g_clear_error(&error);
-                return BT_STATUS_FAIL;
-        }
+       if (error) {
+               ERR("SetAdvertisingData Fail: %s", error->message);
+               g_clear_error(&error);
+               return BT_STATUS_FAIL;
+       }
 
        INFO("Set advertising data");
-        if (ret)
-                g_variant_unref(ret);
+       if (ret)
+               g_variant_unref(ret);
 
        /*
-         * As we need to provide async callback to user from HAL, simply schedule a
-         * callback method which will carry actual result
-         */
+        * As we need to provide async callback to user from HAL, simply schedule a
+        * callback method which will carry actual result
+        */
        event = g_malloc0(sizeof(bt_hal_adv_event_data_t));
        event->event  = BT_HAL_MULTI_ADV_DATA_EVT;
        event->server_if = adv_param_setup.server_if;
        event->status = BT_STATUS_SUCCESS;
        memcpy(&event->data, adv_data, 31);
-        g_idle_add(__bt_hal_adv_event_cb, (gpointer)event);
+       g_idle_add(__bt_hal_adv_event_cb, (gpointer)event);
 
-        return BT_STATUS_SUCCESS;
+       return BT_STATUS_SUCCESS;
 }
 
 int _bt_hal_adapter_le_start_scan(void)
@@ -812,20 +911,58 @@ int _bt_hal_adapter_le_stop_scan(void)
                        -1, NULL, &error);
        if (ret == NULL) {
                if (error) {
+                       g_dbus_error_strip_remote_error(error);
                        ERR("StopLEDiscovery Fail: %s", error->message);
+
+                       /* Abnormal case for ARTIK530 */
+                       if (g_strrstr(error->message, "No discovery started") ||
+                                g_strrstr(error->message, "Operation already in progress")) {
+                               g_clear_error(&error);
+                               return BT_STATUS_SUCCESS;
+                       }
+
                        g_clear_error(&error);
+                       return BT_STATUS_FAIL;
                }
-
-               return BT_STATUS_FAIL;
        }
 
-
        g_variant_unref(ret);
 
        DBG("-");
        return BT_STATUS_SUCCESS;
 }
 
+/*sets the privacy functionality of the adapter*/
+int _bt_hal_adapter_le_set_privacy(uint8_t set_privacy)
+{
+       GDBusProxy *proxy;
+       GError *error = NULL;
+       GVariant *result = NULL;
+       proxy = _bt_hal_get_adapter_proxy();
+       if (proxy == NULL)
+               return BT_STATUS_FAIL;
+
+       result = g_dbus_proxy_call_sync(proxy,
+                               "SetLePrivacy",
+                               g_variant_new("(b)", set_privacy),
+                               G_DBUS_CALL_FLAGS_NONE,
+                               -1,
+                               NULL,
+                               &error);
+
+       if (!result) {
+               if (error != NULL) {
+                       ERR("Failed to SetLePrivacy (Error: %s)", error->message);
+                       g_clear_error(&error);
+               } else
+                       ERR("Failed to SetLePrivacy");
+               return BT_STATUS_FAIL;
+       }
+
+       g_variant_unref(result);
+       INFO("SetLePrivacy as %d", set_privacy);
+       return BT_STATUS_SUCCESS;
+}
 
 int _bt_hal_adapter_le_set_scan_parameters(
                int scan_type, int scan_interval, int scan_window)
@@ -869,3 +1006,97 @@ void _bt_hal_unregister_gatt_le_dbus_handler_cb(void)
 {
        gatt_le_event_cb = NULL;
 }
+
+int _bt_hal_adapter_le_set_manufacturer_data(bt_manufacturer_data_t *m_data)
+{
+       GDBusProxy *proxy;
+       GError *error = NULL;
+       int i;
+       GVariant *val;
+       GVariant *ret;
+       GVariantBuilder *builder;
+
+       proxy = _bt_hal_get_adapter_proxy();
+       if (proxy == NULL)
+               return BT_STATUS_FAIL;
+
+       builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
+
+       if (m_data->data_len + 2 >= BT_MANUFACTURER_DATA_LENGTH_MAX)
+               return BT_STATUS_PARM_INVALID;
+       for (i = 0; i < (m_data->data_len) + 2; i++)
+               g_variant_builder_add(builder, "y", m_data->data[i]);
+
+       val = g_variant_new("(ay)", builder);
+
+       ret = g_dbus_proxy_call_sync(proxy,
+                               "SetManufacturerData",
+                               val,
+                               G_DBUS_CALL_FLAGS_NONE,
+                               -1,
+                               NULL,
+                               &error);
+       g_variant_builder_unref(builder);
+       if (!ret) {
+               if (error != NULL) {
+                       ERR("Failed to SetManufacturerData (Error: %s)", error->message);
+                       g_clear_error(&error);
+               } else {
+                       ERR("Failed to SetManufacturerData");
+               }
+               return BT_STATUS_FAIL;
+       }
+
+       INFO("Set manufacturer data");
+       g_variant_unref(ret);
+
+       return BT_STATUS_SUCCESS;
+}
+
+
+
+/*add/remove remote device address from white list*/
+int _bt_hal_adapter_le_set_white_list(bt_bdaddr_t *device_address, bt_dev_addr_type_t address_type, bool is_add)
+{
+       GDBusProxy *proxy;
+       char address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
+       GError *error = NULL;
+       GVariant *ret;
+
+       if (address_type != BLUETOOTH_HAL_DEVICE_PUBLIC_ADDRESS &&
+               address_type != BLUETOOTH_HAL_DEVICE_RANDOM_ADDRESS)
+               return BT_STATUS_PARM_INVALID;
+
+       _bt_hal_convert_addr_type_to_string(address, device_address->address);
+
+       proxy = _bt_hal_get_adapter_proxy();
+       if (proxy == NULL)
+               return BT_STATUS_FAIL;
+       if (is_add)
+               ret = g_dbus_proxy_call_sync(proxy, "AddDeviceWhiteList",
+                               g_variant_new("(su)", address, address_type),
+                               G_DBUS_CALL_FLAGS_NONE, -1,
+                               NULL, &error);
+       else
+               ret = g_dbus_proxy_call_sync(proxy, "RemoveDeviceWhiteList",
+                               g_variant_new("(su)", address, address_type),
+                               G_DBUS_CALL_FLAGS_NONE, -1,
+                               NULL, &error);
+
+       if (error) {
+               if (is_add)
+                       ERR("RemoveDeviceWhiteList Fail: %s", error->message);
+               else
+                       ERR("AddDeviceWhiteList Fail: %s", error->message);
+               g_clear_error(&error);
+               return BT_STATUS_FAIL;
+       }
+
+       if (ret)
+               g_variant_unref(ret);
+       if (is_add)
+               INFO("Device Added to white list");
+       else
+               INFO("Device Removed from white list");
+       return BT_STATUS_SUCCESS;
+}