Fix paired device array exceed issue
[platform/core/connectivity/bluetooth-frwk.git] / bt-oal / bluez_hal / src / bt-hal-adapter-dbus-handler.c
index 6a9a14d..190d84f 100644 (file)
 #include "bt-hal-msg.h"
 #include "bt-hal-utils.h"
 #include "bt-hal-adapter-le.h"
+#include "bt-hal-adapter-dbus-handler.h"
+#include "bt-hal-dbus-common-utils.h"
 
-#include <bt-hal-adapter-dbus-handler.h>
-#include <bt-hal-dbus-common-utils.h>
+#include "bt-internal-types.h"
 
 #define BT_ENABLE_TIMEOUT 20000 /* 20 seconds */
 #define BT_CORE_NAME "org.projectx.bt_core"
@@ -57,11 +58,9 @@ handle_stack_msg _bt_get_adapter_event_cb(void)
 
 GDBusConnection *__bt_hal_get_system_gconn(void)
 {
-       DBG("+");
        if (system_conn == NULL)
                system_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL);
 
-       DBG("-");
        return system_conn;
 }
 
@@ -69,7 +68,6 @@ GDBusProxy *_bt_init_core_proxy(void)
 {      GDBusProxy *proxy;
        GDBusConnection *conn;
 
-       DBG("+");
        conn = __bt_hal_get_system_gconn();
        if (!conn)
                return NULL;
@@ -86,7 +84,6 @@ GDBusProxy *_bt_init_core_proxy(void)
 
        core_proxy = proxy;
 
-       DBG("-");
        return proxy;
 }
 
@@ -198,10 +195,18 @@ int _bt_hal_dbus_enable_adapter(void)
                g_idle_add(__bt_hal_send_adapter_event, (gpointer)user_data);
                return BT_STATUS_SUCCESS;
        }
+
+       if (TIZEN_FEATURE_BT_USB_DONGLE && powered == 1) {
+               gboolean *user_data = g_new0(int, 1);
+               *user_data = TRUE;
+               g_idle_add(__bt_hal_send_adapter_event, (gpointer)user_data);
+               return BT_STATUS_SUCCESS;
+       }
+
        proxy = __bt_get_core_proxy();
 
        if (!proxy) {
-               DBG("_bt_hal_dbus_enable_adapter: Core proxy get failed!!!");
+               ERR("_bt_hal_dbus_enable_adapter: Core proxy get failed!!!");
                return BT_STATUS_FAIL;
        }
 
@@ -212,7 +217,7 @@ int _bt_hal_dbus_enable_adapter(void)
                        G_DBUS_CALL_FLAGS_NONE, BT_ENABLE_TIMEOUT,
                        NULL, &error);
        if (error) {
-               DBG("EnableAdapter failed: %s", error->message);
+               ERR("EnableAdapter failed: %s", error->message);
                g_clear_error(&error);
                error = NULL;
                _bt_hal_set_adapter_request_state(FALSE);
@@ -226,7 +231,7 @@ int _bt_hal_dbus_enable_adapter(void)
                                &error);
 
                if (error != NULL) {
-                       DBG("Bt core call failed(Error: %s)", error->message);
+                       ERR("Bt core call failed(Error: %s)", error->message);
                        g_clear_error(&error);
                }
                g_variant_unref(result);
@@ -236,7 +241,6 @@ int _bt_hal_dbus_enable_adapter(void)
                return BT_STATUS_FAIL;
        }
 
-       DBG("-");
        g_variant_unref(result);
        return BT_STATUS_SUCCESS;
 }
@@ -249,9 +253,8 @@ int _bt_hal_dbus_disable_adapter(void)
 
        DBG("+");
        proxy = __bt_get_core_proxy();
-
        if (!proxy) {
-               DBG("_bt_hal_dbus_enable_adapter: Core proxy get failed!!!");
+               ERR("_bt_hal_dbus_enable_adapter: Core proxy get failed!!!");
                return BT_STATUS_FAIL;
        }
 
@@ -260,7 +263,7 @@ int _bt_hal_dbus_disable_adapter(void)
                        G_DBUS_CALL_FLAGS_NONE, -1,
                        NULL, &error);
        if (error) {
-               DBG("DisableAdapter failed: %s", error->message);
+               ERR("DisableAdapter failed: %s", error->message);
                g_clear_error(&error);
                error = NULL;
                g_variant_unref(result);
@@ -270,7 +273,34 @@ int _bt_hal_dbus_disable_adapter(void)
                return BT_STATUS_FAIL;
        }
 
-       DBG("-");
+       g_variant_unref(result);
+       return BT_STATUS_SUCCESS;
+}
+
+int _bt_hal_dbus_recover_adapter(void)
+{
+       GDBusProxy *proxy;
+       GVariant *result = NULL;
+       GError *error = NULL;
+
+       DBG("+");
+       proxy = __bt_get_core_proxy();
+       if (!proxy) {
+               ERR("_bt_hal_dbus_recover_adapter: Core proxy get failed!!!");
+               return BT_STATUS_FAIL;
+       }
+
+       result = g_dbus_proxy_call_sync(proxy, "RecoverAdapter",
+                       NULL,
+                       G_DBUS_CALL_FLAGS_NONE, -1,
+                       NULL, &error);
+       if (error) {
+               ERR("RecoverAdapter failed: %s", error->message);
+               g_clear_error(&error);
+               error = NULL;
+               return BT_STATUS_FAIL;
+       }
+
        g_variant_unref(result);
        return BT_STATUS_SUCCESS;
 }
@@ -312,11 +342,11 @@ int _bt_hal_dbus_enable_le(void)
                        G_DBUS_CALL_FLAGS_NONE, BT_ENABLE_TIMEOUT,
                        NULL, &error);
        if (error) {
-               DBG("EnableAdapter failed: %s", error->message);
+               DBG("EnableAdapterLe failed: %s", error->message);
                g_clear_error(&error);
                error = NULL;
                result = g_dbus_proxy_call_sync(proxy,
-                               "DisableAdapter",
+                               "DisableAdapterLe",
                                NULL,
                                G_DBUS_CALL_FLAGS_NONE,
                                -1,
@@ -478,8 +508,11 @@ int _bt_hal_dbus_stop_discovery(void)
        GDBusProxy *proxy;
        GError *error = NULL;
        GVariant *result;
+       struct hal_ev_discovery_state_changed ev;
        DBG("+");
 
+       memset(&ev, 0, sizeof(ev));
+
        proxy = _bt_hal_get_adapter_proxy();
        if (!proxy) {
                DBG("_bt_hal_dbus_stop_discovery: Adapter proxy get failed!!!");
@@ -503,12 +536,183 @@ int _bt_hal_dbus_stop_discovery(void)
                return BT_STATUS_FAIL;
        }
 
+       /* Stop success */
+       ev.state = HAL_DISCOVERY_STATE_STOPPED;
+
+       if (!event_cb)
+               event_cb = _bt_hal_get_stack_message_handler();
+       if (event_cb) {
+               DBG("Sending HAL_EV_DISCOVERY_STATE_CHANGED event");
+               event_cb(HAL_EV_DISCOVERY_STATE_CHANGED, (void*)&ev, sizeof(ev));
+       }
+
        /* discovery status will be change in event */
        DBG("-");
        g_variant_unref(result);
        return BT_STATUS_SUCCESS;
 }
 
+int _bt_hal_dbus_get_energy_info(uint32_t *tx_time, uint32_t *rx_time,
+                                       uint32_t *idle_time, uint32_t *energy_used)
+{
+       GDBusProxy *proxy;
+       GError *error = NULL;
+       GVariant *result;
+
+       if (!tx_time || !rx_time || !idle_time || !energy_used) {
+               ERR("Invalid parameter");
+               return BT_STATUS_FAIL;
+       }
+
+       proxy = _bt_hal_get_adapter_proxy();
+       if (!proxy) {
+               DBG("_bt_hal_dbus_get_energy_info: Adapter proxy get failed!!!");
+               return BT_STATUS_FAIL;
+       }
+
+       result = g_dbus_proxy_call_sync(proxy,
+                       "GetEnergyInfo",
+                       NULL,
+                       G_DBUS_CALL_FLAGS_NONE,
+                       -1,
+                       NULL,
+                       &error);
+
+       if (!result) {
+               if (error != NULL) {
+                       ERR("GetEnergyInfo failed (Error: %s)", error->message);
+                       g_clear_error(&error);
+               } else {
+                       ERR("GetEnergyInfo failed");
+               }
+               return BT_STATUS_FAIL;
+       }
+
+       g_variant_get(result, "(uuuu)", tx_time, rx_time, idle_time, energy_used);
+
+       DBG("Tx time: %d, Rx time: %d, Idle time: %d", *tx_time, *rx_time, *idle_time);
+
+       g_variant_unref(result);
+       return BT_STATUS_SUCCESS;
+}
+
+int _bt_hal_dbus_get_profile_connected_devices(const char *profile_uuid)
+{
+       GDBusConnection *conn;
+       GDBusProxy *manager_proxy;
+       GVariant *result = NULL;
+       GVariant *result1 = NULL;
+       GVariantIter *iter = NULL;
+       GError *error = NULL;
+       char *object_path = NULL;
+       GVariantIter *interface_iter;
+       char *interface_str = NULL;
+       GDBusProxy *device_proxy = NULL;
+       gboolean is_connected = FALSE;
+       struct hal_ev_adapter_profile_connected_devices ev;
+
+       DBG("Get Profile Connected Devices. UUID: %s", profile_uuid);
+       memset(&ev, 0, sizeof(ev));
+
+       conn = __bt_hal_get_system_gconn();
+       if (conn == NULL)
+               return BT_STATUS_FAIL;
+
+       manager_proxy = _bt_hal_get_manager_proxy();
+       if (manager_proxy == NULL)
+               return  BT_STATUS_FAIL;
+
+       result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
+                       NULL,
+                       G_DBUS_CALL_FLAGS_NONE,
+                       -1,
+                       NULL,
+                       &error);
+
+       if (!result) {
+               if (error != NULL) {
+                       ERR("GetManagedObjects failed (Error: %s)", error->message);
+                       g_clear_error(&error);
+                       error = NULL;
+               } else
+                       ERR("GetManagedObjects failed");
+               return BT_STATUS_FAIL;
+       }
+
+       /* signature of GetManagedObjects:  a{oa{sa{sv}}} */
+       g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
+
+       /* Parse the signature:  oa{sa{sv}}} */
+       while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path, &interface_iter)) {
+               if (object_path == NULL)
+                       continue;
+
+               while (g_variant_iter_loop(interface_iter, "{sa{sv}}",
+                                       &interface_str, NULL)) {
+                       if (g_strcmp0(interface_str, "org.bluez.Device1") == 0) {
+                               DBG("Found a device: %s", object_path);
+                               g_free(interface_str);
+
+                               device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
+                                               NULL, BT_HAL_BLUEZ_NAME,
+                                               object_path, BT_HAL_DEVICE_INTERFACE,  NULL, NULL);
+
+                               if (device_proxy == NULL) {
+                                       DBG("Device don't have this service");
+                                       break;
+                               }
+
+                               result1 = g_dbus_proxy_call_sync(device_proxy, "IsConnectedProfile",
+                                               g_variant_new("(s)", profile_uuid),
+                                               G_DBUS_CALL_FLAGS_NONE,
+                                               -1,
+                                               NULL,
+                                               &error);
+
+                               if (result1 == NULL) {
+                                       if (error) {
+                                               ERR("Error occured in Proxy call [%s]", error->message);
+                                               g_error_free(error);
+                                               error = NULL;
+                                       }
+                                       g_object_unref(device_proxy);
+                                       break;
+                               }
+                               g_variant_get(result1, "(b)", &is_connected);
+
+                               if (is_connected == TRUE) {
+                                       char address[BT_HAL_ADDRESS_STRING_SIZE];
+                                       _bt_hal_convert_device_path_to_address(object_path, address);
+                                       DBG("Address: %s", address);
+                                       if (ev.count >= 10) {
+                                               INFO("Too many address");
+                                               break;
+                                       }
+                                       _bt_hal_convert_addr_string_to_type(ev.bdaddr_list[ev.count], address);
+                                       ev.count++;
+                               }
+
+                               g_variant_unref(result1);
+                               g_object_unref(device_proxy);
+                               break;
+                       }
+               }
+       }
+
+       if (!event_cb)
+               event_cb = _bt_hal_get_stack_message_handler();
+       if (event_cb) {
+               DBG("Sending HAL_EV_ADAPTER_PROFILE_CONNECTED_DEVICES event");
+               event_cb(HAL_EV_ADAPTER_PROFILE_CONNECTED_DEVICES, (void *)&ev, sizeof(ev));
+       }
+
+       g_variant_unref(result);
+       g_variant_iter_free(iter);
+
+       DBG("-");
+       return BT_STATUS_SUCCESS;
+}
+
 static gboolean __bt_adapter_all_properties_cb(gpointer user_data)
 {
        GVariant *result = user_data;
@@ -673,6 +877,7 @@ static gboolean __bt_adapter_all_properties_cb(gpointer user_data)
                                        _bt_hal_update_le_feature_support(name, val, &le_features);
                                        le_features_present = TRUE;
                                }
+                               g_free(val);
                                g_variant_iter_free(iter);
 
                                if (le_features_present) {
@@ -714,6 +919,7 @@ static gboolean __bt_adapter_all_properties_cb(gpointer user_data)
        }
 done:
        g_variant_unref(result);
+       g_variant_iter_free(property_iter);
        return FALSE;
 }
 
@@ -777,7 +983,7 @@ int _bt_hal_get_adapter_powered_state(uint8_t *state)
        adapter_path = _bt_hal_get_adapter_path();
 
        if (adapter_path == NULL) {
-               INFO("Adapter is not powered");
+               INFO("adapter_path is NULL");
                g_free(adapter_path);
                *state = 0;
                return ret;
@@ -792,6 +998,8 @@ int _bt_hal_get_adapter_powered_state(uint8_t *state)
                return ret;
        }
 
+       g_free(adapter_path);
+
        if (powered)
                *state = 1;
        else
@@ -896,6 +1104,50 @@ int _bt_hal_dbus_get_discovery_timeout(void)
        return BT_STATUS_SUCCESS;
 }
 
+int _bt_hal_dbus_get_adapter_class(unsigned int *adapter_class)
+{
+       GDBusProxy *proxy;
+       GVariant *result;
+       GVariant *temp;
+       GError *error = NULL;
+       DBG("+");
+
+       proxy = _bt_hal_get_adapter_properties_proxy();
+       if (!proxy) {
+               DBG("Adapter Properties proxy get failed!!!");
+               return BT_STATUS_FAIL;
+       }
+
+       result = g_dbus_proxy_call_sync(proxy,
+                       "Get",
+                       g_variant_new("(ss)", BT_HAL_ADAPTER_INTERFACE,
+                               "Class"),
+                       G_DBUS_CALL_FLAGS_NONE,
+                       -1,
+                       NULL,
+                       &error);
+
+       if (!result) {
+               if (error != NULL) {
+                       ERR("Failed to get class (Error: %s)", error->message);
+                       g_clear_error(&error);
+               } else
+                       ERR("Failed to get class");
+               return BT_STATUS_FAIL;
+       }
+
+
+       g_variant_get(result, "(v)", &temp);
+       *adapter_class = g_variant_get_uint32(temp);
+       DBG("Class value: [0x%06x]", *adapter_class);
+
+       g_variant_unref(result);
+       g_variant_unref(temp);
+
+       DBG("-");
+       return BT_STATUS_SUCCESS;
+}
+
 /* Get Discoverable Mode API and callback */
 static gboolean __bt_adapter_scan_mode_cb(gpointer user_data)
 {
@@ -938,8 +1190,8 @@ done:
 int _bt_hal_dbus_get_scan_mode(void)
 {
        GDBusProxy *proxy;
-       gboolean discoverable;
-       gboolean connectable;
+       gboolean discoverable = FALSE;
+       gboolean connectable = FALSE;
        GVariant *result;
        GVariant *temp;
        GError *error = NULL;
@@ -1164,11 +1416,10 @@ int _bt_hal_dbus_get_local_name(void)
        GVariant *result;
        GVariant *temp;
        GError *error = NULL;
-       DBG("+");
 
        proxy = _bt_hal_get_adapter_properties_proxy();
        if (!proxy) {
-               DBG("_bt_hal_dbus_get_local_name: Adapter Properties proxy get failed!!!");
+               DBG("Adapter Properties proxy get failed!!!");
                return BT_STATUS_FAIL;
        }
 
@@ -1203,7 +1454,6 @@ int _bt_hal_dbus_get_local_name(void)
         */
        g_idle_add(__bt_adapter_local_name_cb, (gpointer) name);
 
-       DBG("-");
        return BT_STATUS_SUCCESS;
 }
 
@@ -1260,8 +1510,6 @@ int _bt_hal_dbus_get_local_address(void)
        GVariant *result;
        GVariant *temp;
 
-       DBG("+");
-
        proxy = _bt_hal_get_adapter_properties_proxy();
        if (!proxy) {
                DBG("_bt_hal_dbus_get_local_address: Adapter Properties proxy get failed!!!");
@@ -1303,7 +1551,6 @@ int _bt_hal_dbus_get_local_address(void)
         */
        g_idle_add(__bt_adapter_local_address_cb, (gpointer) address);
 
-       DBG("-");
        return BT_STATUS_SUCCESS;
 }
 
@@ -1389,12 +1636,9 @@ int _bt_hal_dbus_get_adapter_supported_uuids(void)
        GError *error = NULL;
        GVariant *result;
 
-       DBG("+");
-
        proxy = _bt_hal_get_adapter_properties_proxy();
-
        if (!proxy) {
-               DBG("_bt_hal_dbus_get_local_name: Adapter Properties proxy get failed!!!");
+               DBG("Adapter Properties proxy get failed!!!");
                return BT_STATUS_FAIL;
        }
 
@@ -1425,7 +1669,6 @@ int _bt_hal_dbus_get_adapter_supported_uuids(void)
         */
        g_idle_add(__bt_adapter_service_uuids_cb, (gpointer)result);
 
-       DBG("-");
        return BT_STATUS_SUCCESS;
 }
 
@@ -1453,7 +1696,7 @@ static gboolean __bt_adapter_bonded_devices_cb(gpointer user_data)
        /* Buffer and propety count management */
        uint8_t buf[BT_HAL_MAX_PROPERTY_BUF_SIZE];
        uint8_t addresses[BT_HAL_MAX_PROPERTY_BUF_SIZE];
-       struct hal_ev_adapter_props_changed *ev = (void*) buf;;
+       struct hal_ev_adapter_props_changed *ev = (void *)buf;
        size_t size = 0;
        size_t count = 0;
 
@@ -1501,6 +1744,11 @@ static gboolean __bt_adapter_bonded_devices_cb(gpointer user_data)
                                break;
                        }
                }
+
+               if (count >= (int)(sizeof(addresses) / BT_HAL_ADDRESS_LENGTH_MAX)) {
+                       DBG("Reached the max length of addresses. do not stored anymore");
+                       break;
+               }
        }
 
        g_variant_iter_free(iter);
@@ -1532,8 +1780,6 @@ int _bt_hal_dbus_get_bonded_devices(void)
        GDBusProxy *manager_proxy;
        GVariant *result = NULL;
 
-       DBG("+");
-
        manager_proxy = _bt_hal_get_manager_proxy();
        if (manager_proxy == NULL)
                return  BT_STATUS_FAIL;
@@ -1555,15 +1801,12 @@ int _bt_hal_dbus_get_bonded_devices(void)
         */
        g_idle_add(__bt_adapter_bonded_devices_cb, (gpointer) result);
 
-       DBG("-");
        return BT_STATUS_SUCCESS;
 }
 
 int _bt_hal_dbus_get_adapter_property(bt_property_type_t property_type)
 {
-       DBG("+");
-
-       INFO("property_type: %d", property_type);
+       DBG("property_type: %d", property_type);
 
        switch (property_type) {
        case BT_PROPERTY_BDADDR:
@@ -1585,8 +1828,6 @@ int _bt_hal_dbus_get_adapter_property(bt_property_type_t property_type)
        default:
                return BT_STATUS_UNSUPPORTED;
        }
-
-       DBG("-");
 }
 
 static int __bt_hal_dbus_set_local_name(void *data)
@@ -1596,7 +1837,6 @@ static int __bt_hal_dbus_set_local_name(void *data)
        GVariant *result;
        GError *error = NULL;
 
-       DBG("+");
        DBG("Local Name: [%s]", name);
        proxy = _bt_hal_get_adapter_properties_proxy();
        if (!proxy) {
@@ -1622,7 +1862,6 @@ static int __bt_hal_dbus_set_local_name(void *data)
        }
        g_variant_unref(result);
 
-       DBG("-");
        return BT_STATUS_SUCCESS;
 }
 
@@ -1635,7 +1874,6 @@ static int __bt_hal_dbus_set_scan_mode(void *data)
        gboolean pg_scan;
        gboolean inq_scan;
 
-       DBG("+");
        DBG("Scan mode: [%d]", *mode);
        proxy = _bt_hal_get_adapter_properties_proxy();
        if (!proxy) {
@@ -1697,7 +1935,6 @@ static int __bt_hal_dbus_set_scan_mode(void *data)
        }
        g_variant_unref(result);
 
-       DBG("-");
        return BT_STATUS_SUCCESS;
 }
 
@@ -1708,9 +1945,6 @@ static int __bt_hal_dbus_set_discovery_timeout(void *data)
        GVariant *result;
        GError *error = NULL;
 
-
-       DBG("+");
-
        DBG("Discovery Timeout: [%d]", *timeout);
        proxy = _bt_hal_get_adapter_properties_proxy();
        if (!proxy) {
@@ -1736,7 +1970,6 @@ static int __bt_hal_dbus_set_discovery_timeout(void *data)
        }
        g_variant_unref(result);
 
-       DBG("-");
        return BT_STATUS_SUCCESS;
 }
 
@@ -1745,8 +1978,6 @@ int _bt_hal_dbus_set_adapter_property(const bt_property_t *property)
 {
        int result;
 
-       DBG("");
-
        if (property == NULL || property->val == NULL) {
                ERR("Invalid parameters received");
                return BT_STATUS_FAIL;
@@ -1766,6 +1997,5 @@ int _bt_hal_dbus_set_adapter_property(const bt_property_t *property)
                result = BT_STATUS_UNSUPPORTED;
        }
 
-       DBG("Result= [%d]", result);
        return result;
 }