X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=bt-service%2Fbt-service-adapter.c;h=078bca794e54f3665d7ff95fcb45121daa6bae19;hb=058d1c9bffbd8b4be2f16e8d55796afc7f8c4704;hp=6be1d05c8405a6fd7fea558bd9b1e5c5e0a5a01c;hpb=58266d84210161141befe39e1a6f4a79fdfc5b96;p=platform%2Fcore%2Fconnectivity%2Fbluetooth-frwk.git diff --git a/bt-service/bt-service-adapter.c b/bt-service/bt-service-adapter.c index 6be1d05..078bca7 100644 --- a/bt-service/bt-service-adapter.c +++ b/bt-service/bt-service-adapter.c @@ -1,11 +1,5 @@ /* - * Bluetooth-frwk - * - * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. - * - * Contact: Hocheol Seo - * Girishashok Joshi - * Chanyeol Park + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,20 +21,12 @@ #include #include #include -#if !defined(LIBNOTIFY_SUPPORT) && !defined(LIBNOTIFICATION_SUPPORT) #include -#endif #include -#ifdef ENABLE_TIZEN_2_4 -#include -#endif #include #include - #include -#if 0 #include -#endif #include #include "alarm.h" @@ -52,31 +38,53 @@ #include "bt-service-util.h" #include "bt-service-network.h" #include "bt-service-obex-server.h" +#include "bt-service-opp-client.h" #include "bt-service-agent.h" #include "bt-service-main.h" #include "bt-service-avrcp.h" #include "bt-service-device.h" +#include "bt-service-adapter-le.h" + +#ifdef TIZEN_DPM_ENABLE +#include "bt-service-dpm.h" +#endif typedef struct { guint event_id; int timeout; time_t start_time; - gboolean alarm_init; int alarm_id; } bt_adapter_timer_t; bt_adapter_timer_t visible_timer = {0, }; +typedef struct { + alarm_id_t alarm_id; + bt_set_alarm_cb callback; + void *user_data; +} bt_service_alarm_t; + +typedef struct { + gboolean is_alarm_initialized; + GList *g_alarm_list; +} bt_service_alarm_mgr_t; + +static bt_service_alarm_mgr_t alarm_mgr = {0, }; + static gboolean is_discovering; static gboolean cancel_by_user; static bt_status_t adapter_status = BT_DEACTIVATED; static bt_le_status_t adapter_le_status = BT_LE_DEACTIVATED; +static gboolean is_le_intended = FALSE; static void *adapter_agent = NULL; static GDBusProxy *core_proxy = NULL; static guint timer_id = 0; static guint le_timer_id = 0; +static gboolean is_recovery_mode; +static gboolean in_power_off; -static int status_reg_id; +static guint poweroff_subscribe_id; +static uint status_reg_id; #define BT_CORE_NAME "org.projectx.bt_core" #define BT_CORE_PATH "/org/projectx/bt_core" @@ -84,12 +92,15 @@ static int status_reg_id; #define BT_DISABLE_TIME 500 /* 500 ms */ +static int alarm_cb(alarm_id_t alarm_id, void* user_param); +static void alarm_data_free(void *data); + GDBusProxy *_bt_init_core_proxy(void) { GDBusProxy *proxy; GDBusConnection *conn; - conn = _bt_get_system_gconn(); + conn = _bt_gdbus_get_system_gconn(); if (!conn) return NULL; @@ -110,19 +121,17 @@ GDBusProxy *_bt_init_core_proxy(void) static GDBusProxy *__bt_get_core_proxy(void) { - return (core_proxy) ? core_proxy : _bt_init_core_proxy(); + return (core_proxy) ? core_proxy : _bt_init_core_proxy(); } static gboolean __bt_is_factory_test_mode(void) { int mode = 0; -#ifdef ENABLE_TIZEN_2_4 if (vconf_get_bool(VCONFKEY_BT_DUT_MODE, &mode)) { BT_ERR("Get the DUT Mode fail"); return TRUE; } -#endif if (mode != FALSE) { BT_INFO("DUT Test Mode !!"); @@ -152,7 +161,7 @@ static gboolean __bt_timeout_handler(gpointer user_data) visible_timer.event_id = 0; visible_timer.timeout = 0; -#ifndef TIZEN_WEARABLE +#ifndef TIZEN_PROFILE_WEARABLE if (vconf_set_int(BT_FILE_VISIBLE_TIME, 0) != 0) BT_ERR("Set vconf failed\n"); #endif @@ -164,7 +173,6 @@ static gboolean __bt_timeout_handler(gpointer user_data) static int __bt_visibility_alarm_cb(alarm_id_t alarm_id, void* user_param) { - BT_DBG("__bt_visibility_alarm_cb - alram id = [%d] \n", alarm_id); int result = BLUETOOTH_ERROR_NONE; int timeout = 0; @@ -180,7 +188,7 @@ static int __bt_visibility_alarm_cb(alarm_id_t alarm_id, void* user_param) visible_timer.event_id = 0; visible_timer.timeout = 0; -#ifndef TIZEN_WEARABLE +#ifndef TIZEN_PROFILE_WEARABLE if (vconf_set_int(BT_FILE_VISIBLE_TIME, 0) != 0) BT_ERR("Set vconf failed\n"); #endif @@ -191,21 +199,6 @@ static int __bt_visibility_alarm_cb(alarm_id_t alarm_id, void* user_param) return 0; } -static void __bt_visibility_alarm_create() -{ - alarm_id_t alarm_id; - int result; - - result = alarmmgr_add_alarm(ALARM_TYPE_VOLATILE, visible_timer.timeout, - 0, NULL, &alarm_id); - if(result < 0) { - BT_ERR("Failed to create alarm error = %d\n", result); - } else { - BT_DBG("Alarm created = %d\n", alarm_id); - visible_timer.alarm_id = alarm_id; - } -} - static void __bt_visibility_alarm_remove() { if (visible_timer.event_id > 0) { @@ -214,7 +207,7 @@ static void __bt_visibility_alarm_remove() } if (visible_timer.alarm_id > 0) { - alarmmgr_remove_alarm(visible_timer.alarm_id); + _bt_service_remove_alarm(visible_timer.alarm_id); visible_timer.alarm_id = 0; } } @@ -222,39 +215,37 @@ static void __bt_visibility_alarm_remove() int __bt_set_visible_time(int timeout) { int result; + alarm_id_t alarm_id; __bt_visibility_alarm_remove(); visible_timer.timeout = timeout; - if (timeout <= 0) - return BLUETOOTH_ERROR_NONE; - -#ifndef TIZEN_WEARABLE +#ifndef TIZEN_PROFILE_WEARABLE +#ifdef TIZEN_DPM_ENABLE + if (_bt_dpm_get_bluetooth_limited_discoverable_state() != DPM_RESTRICTED) { +#endif if (vconf_set_int(BT_FILE_VISIBLE_TIME, timeout) != 0) BT_ERR("Set vconf failed"); +#ifdef TIZEN_DPM_ENABLE + } +#endif #endif - if (!visible_timer.alarm_init) { - /* Set Alarm timer to switch off BT */ - result = alarmmgr_init("bt-service"); - if (result != 0) - return BLUETOOTH_ERROR_INTERNAL; - visible_timer.alarm_init = TRUE; - } + if (timeout <= 0) + return BLUETOOTH_ERROR_NONE; - result = alarmmgr_set_cb(__bt_visibility_alarm_cb, NULL); - if (result != 0) + result = _bt_service_set_alarm(visible_timer.timeout, + __bt_visibility_alarm_cb, NULL, &alarm_id); + if (result != BLUETOOTH_ERROR_NONE) return BLUETOOTH_ERROR_INTERNAL; - + visible_timer.alarm_id = alarm_id; /* Take start time */ time(&(visible_timer.start_time)); visible_timer.event_id = g_timeout_add_seconds(1, __bt_timeout_handler, NULL); - __bt_visibility_alarm_create(); - return BLUETOOTH_ERROR_NONE; } @@ -294,8 +285,9 @@ static int __bt_get_bonded_device_info(gchar *device_path, { GError *error = NULL; GDBusProxy *device_proxy; - const gchar *address = NULL; - const gchar *name = NULL; + gchar *address = NULL; + gchar *name = NULL; + gchar *alias = NULL; unsigned int cod = 0; gint rssi = 0; gboolean trust = FALSE; @@ -314,7 +306,7 @@ static int __bt_get_bonded_device_info(gchar *device_path, BT_CHECK_PARAMETER(device_path, return); BT_CHECK_PARAMETER(dev_info, return); - conn = _bt_get_system_gconn(); + conn = _bt_gdbus_get_system_gconn(); retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL); device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE, @@ -349,15 +341,14 @@ static int __bt_get_bonded_device_info(gchar *device_path, g_variant_get(result, "(a{sv})", &property_iter); while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) { - if (!g_strcmp0(key,"Paired")) { + if (!g_strcmp0(key, "Paired")) { paired = g_variant_get_boolean(value); - } else if(!g_strcmp0(key, "Address")) { - address = g_variant_get_string(value, NULL); + } else if (!g_strcmp0(key, "Address")) { + g_variant_get(value, "s", &address); } else if (!g_strcmp0(key, "Alias")) { - name = g_variant_get_string(value, NULL); + g_variant_get(value, "s", &alias); } else if (!g_strcmp0(key, "Name")) { - if (!name) - name = g_variant_get_string(value, NULL); + g_variant_get(value, "s", &name); } else if (!g_strcmp0(key, "Class")) { cod = g_variant_get_uint32(value); } else if (!g_strcmp0(key, "Connected")) { @@ -368,28 +359,35 @@ static int __bt_get_bonded_device_info(gchar *device_path, rssi = g_variant_get_int16(value); } else if (!g_strcmp0(key, "UUIDs")) { __bt_get_service_list(value, dev_info); - } else if (!g_strcmp0(key, "ManufacturerDataLen")) { + } else if (!g_strcmp0(key, "LegacyManufacturerDataLen")) { dev_info->manufacturer_data.data_len = g_variant_get_uint16(value); - } else if (!g_strcmp0(key, "ManufacturerData")) { + } else if (!g_strcmp0(key, "LegacyManufacturerData")) { manufacturer_data = g_byte_array_new(); g_variant_get(value, "ay", &char_value_iter); - while(g_variant_iter_loop(char_value_iter, "y", &char_value)) { + while (g_variant_iter_loop(char_value_iter, "y", &char_value)) g_byte_array_append(manufacturer_data, &char_value, 1); - } + + g_variant_iter_free(char_value_iter); + if (manufacturer_data) { if (manufacturer_data->len > 0) { memcpy(dev_info->manufacturer_data.data, manufacturer_data->data, manufacturer_data->len); } } + g_byte_array_free(manufacturer_data, TRUE); } } + g_variant_iter_free(property_iter); BT_DBG("trust: %d, paired: %d", trust, paired); g_variant_unref(result); if ((paired == FALSE) && (trust == FALSE)) { + g_free(address); + g_free(alias); + g_free(name); return BLUETOOTH_ERROR_NOT_PAIRED; } @@ -398,7 +396,7 @@ static int __bt_get_bonded_device_info(gchar *device_path, _bt_divide_device_class(&dev_info->device_class, cod); - g_strlcpy(dev_info->device_name.name, name, + g_strlcpy(dev_info->device_name.name, alias ? alias : name, BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1); dev_info->rssi = rssi; @@ -406,6 +404,9 @@ static int __bt_get_bonded_device_info(gchar *device_path, dev_info->paired = paired; dev_info->connected = connected; ret = BLUETOOTH_ERROR_NONE; + g_free(address); + g_free(alias); + g_free(name); return ret; } @@ -447,6 +448,23 @@ bt_le_status_t _bt_adapter_get_le_status(void) return adapter_le_status; } + +void _bt_set_le_intended_status(gboolean value) +{ + is_le_intended = value; +} + +static void __bt_set_in_poweroff(void) +{ + BT_INFO("Set in_power_off to TRUE"); + in_power_off = TRUE; +} + +static gboolean __bt_is_in_poweroff(void) +{ + return in_power_off; +} + static void __bt_phone_name_changed_cb(keynode_t *node, void *data) { char *phone_name = NULL; @@ -459,59 +477,55 @@ static void __bt_phone_name_changed_cb(keynode_t *node, void *data) phone_name = vconf_keynode_get_str(node); if (phone_name && strlen(phone_name) != 0) { - if (!g_utf8_validate(phone_name, -1, + if (!g_utf8_validate(phone_name, -1, (const char **)&ptr)) - *ptr = '\0'; + *ptr = '\0'; + BT_INFO("device_name is changed to %s", phone_name); _bt_set_local_name(phone_name); + } else { + BT_ERR("phone_name is NOT valid"); } + } else { + BT_ERR("vconf type is NOT string"); } } -#ifndef TIZEN_WEARABLE -static void __bt_set_visible_mode(void) -{ - int timeout = 0; - - if (vconf_get_int(BT_FILE_VISIBLE_TIME, &timeout) != 0) - BT_ERR("Fail to get the timeout value"); - - if (timeout == -1) { - if (_bt_set_discoverable_mode( - BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE, - timeout) != BLUETOOTH_ERROR_NONE) { - if (vconf_set_int(BT_FILE_VISIBLE_TIME, 0) != 0) - BT_ERR("Set vconf failed"); - } - } -} -#endif - static void __bt_set_local_name(void) { + bluetooth_device_name_t local_name; char *phone_name = NULL; char *ptr = NULL; + char *temp = NULL; - phone_name = vconf_get_str(VCONFKEY_SETAPPL_DEVICE_NAME_STR); + if (_bt_get_local_name(&local_name) != BLUETOOTH_ERROR_NONE || + (temp = strstr(local_name.name, "BlueZ")) != NULL) { + phone_name = vconf_get_str(VCONFKEY_SETAPPL_DEVICE_NAME_STR); - if (!phone_name) - return; + if (!phone_name) + return; - if (strlen(phone_name) != 0) { - if (!g_utf8_validate(phone_name, -1, (const char **)&ptr)) - *ptr = '\0'; + if (strlen(phone_name) != 0) { + if (!g_utf8_validate(phone_name, -1, (const char **)&ptr)) + *ptr = '\0'; - _bt_set_local_name(phone_name); + _bt_set_local_name(phone_name); + } + free(phone_name); } - free(phone_name); } static int __bt_set_enabled(void) { - BT_DBG("+"); int adapter_status = BT_ADAPTER_DISABLED; int result = BLUETOOTH_ERROR_NONE; + if (timer_id > 0) { + BT_DBG("g_source is removed"); + g_source_remove(timer_id); + timer_id = 0; + } + _bt_check_adapter(&adapter_status); if (adapter_status == BT_ADAPTER_DISABLED) { @@ -519,11 +533,18 @@ static int __bt_set_enabled(void) return BLUETOOTH_ERROR_INTERNAL; } -#ifndef TIZEN_WEARABLE - __bt_set_visible_mode(); +#ifdef TIZEN_PROFILE_MOBILE || defined(TIZEN_PROFILE_IVI) + /* BT setting UI will control Mobile's visible mode. So in the FRWK...set the visible mode as off: */ + if (_bt_set_discoverable_mode( + BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE, 0) != BLUETOOTH_ERROR_NONE) + BT_ERR("Set connectable mode failed"); +#else +#ifdef TIZEN_TV + if (_bt_set_discoverable_mode( + BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE, 0) != BLUETOOTH_ERROR_NONE) + BT_ERR("Fail to set discoverable mode"); +#endif #endif - - __bt_set_local_name(); /* Update Bluetooth Status to notify other modules */ if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_ON) != 0) @@ -531,16 +552,21 @@ static int __bt_set_enabled(void) if (vconf_set_int(VCONFKEY_BT_DEVICE, VCONFKEY_BT_DEVICE_NONE) != 0) BT_ERR("Set vconf failed\n"); -#if 0 + if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_STATE, EVT_VAL_BT_ON) != ES_R_OK) BT_ERR("Fail to set value"); -#endif /* Send enabled event to API */ _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_ENABLED, g_variant_new("(i)", result)); - BT_DBG("-"); + +#ifdef TIZEN_BT_A2DP_SINK_AUTO_CONNECT + _bt_audio_start_auto_connect(FALSE); +#endif + + __bt_set_local_name(); + _bt_set_discovery_status(FALSE); return BLUETOOTH_ERROR_NONE; } @@ -558,37 +584,40 @@ void _bt_set_disabled(int result) ret_pm_ignore = vconf_get_int(VCONFKEY_PM_KEY_IGNORE, &pm_ignore_mode); /* Update the vconf BT status in normal Deactivation case only */ - -#if 0 if (ret == 0 && power_off_status == VCONFKEY_SYSMAN_POWER_OFF_NONE && ret_pm_ignore == 0 && pm_ignore_mode != VCONFKEY_PM_KEY_LOCK) { -#endif + BT_DBG("Update vconf for BT normal Deactivation"); if (result == BLUETOOTH_ERROR_TIMEOUT) - if (vconf_set_int(BT_OFF_DUE_TO_TIMEOUT, 1) != 0 ) + if (vconf_set_int(BT_OFF_DUE_TO_TIMEOUT, 1) != 0) BT_ERR("Set vconf failed"); /* Update Bluetooth Status to notify other modules */ if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_OFF) != 0) BT_ERR("Set vconf failed"); -#if 0 + if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_STATE, EVT_VAL_BT_OFF) != ES_R_OK) BT_ERR("Fail to set value"); -#endif -// + } if (vconf_set_int(VCONFKEY_BT_DEVICE, VCONFKEY_BT_DEVICE_NONE) != 0) BT_ERR("Set vconf failed\n"); + _bt_cancel_queued_transfers(); _bt_adapter_set_status(BT_DEACTIVATED); + _bt_set_discovery_status(FALSE); +#ifndef USB_BLUETOOTH if (_bt_adapter_get_le_status() != BT_LE_DEACTIVATED) { +#endif /* Send disabled event */ _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_DISABLED, g_variant_new("(i)", result)); +#ifndef USB_BLUETOOTH } +#endif BT_INFO("Adapter disabled"); } @@ -599,17 +628,17 @@ static int __bt_set_le_enabled(void) int result = BLUETOOTH_ERROR_NONE; bt_status_t status; - __bt_set_local_name(); - /* Update Bluetooth Status to notify other modules */ if (vconf_set_int(VCONFKEY_BT_LE_STATUS, VCONFKEY_BT_LE_STATUS_ON) != 0) - BT_ERR("Set vconf failed\n"); + BT_ERR("Set vconf failed"); + + /* set packet length to max size to enable packet length extension */ + if (BLUETOOTH_ERROR_NONE != _bt_le_set_max_packet_len()) + BT_ERR("Fail to set max packet length"); -#if 0 if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_LE_STATE, EVT_VAL_BT_LE_ON) != ES_R_OK) BT_ERR("Fail to set value"); -#endif /* Send enabled event to API */ /* @@ -630,6 +659,8 @@ static int __bt_set_le_enabled(void) _bt_send_event(BT_LE_ADAPTER_EVENT, BLUETOOTH_EVENT_LE_ENABLED, g_variant_new("(i)", result)); + __bt_set_local_name(); + BT_DBG("-"); return BLUETOOTH_ERROR_NONE; } @@ -645,21 +676,17 @@ void _bt_set_le_disabled(int result) /* Update Bluetooth Status to notify other modules */ BT_DBG("Update vconf for BT LE normal Deactivation"); - if (vconf_set_int(VCONFKEY_BT_LE_STATUS, VCONFKEY_BT_LE_STATUS_OFF) != 0) BT_ERR("Set vconf failed\n"); _bt_adapter_set_le_status(BT_LE_DEACTIVATED); -#if 0 + if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_LE_STATE, EVT_VAL_BT_LE_OFF) != ES_R_OK) BT_ERR("Fail to set value"); -#endif - if (_bt_adapter_get_status() != BT_DEACTIVATED) { - /* Send disabled event */ - _bt_send_event(BT_LE_ADAPTER_EVENT, BLUETOOTH_EVENT_LE_DISABLED, - g_variant_new_int32(result)); - } + /* Send disabled event */ + _bt_send_event(BT_LE_ADAPTER_EVENT, BLUETOOTH_EVENT_LE_DISABLED, + g_variant_new("(i)", result)); } void *_bt_get_adapter_agent(void) @@ -698,7 +725,7 @@ int _bt_enable_core(void) return BLUETOOTH_ERROR_NONE; } -#if defined(TIZEN_BT_FLIGHTMODE_ENABLED) || !defined(TIZEN_WEARABLE) +#if defined(TIZEN_FEATURE_FLIGHTMODE_ENABLED) || (!defined(TIZEN_PROFILE_WEARABLE)) static void __bt_service_flight_ps_mode_cb(keynode_t *node, void *data) { gboolean flight_mode = FALSE; @@ -728,11 +755,58 @@ static void __bt_service_flight_ps_mode_cb(keynode_t *node, void *data) } #endif +static void __bt_poweroff_event_filter(GDBusConnection *connection, + const gchar *sender_name, const gchar *object_path, + const gchar *interface_name, const gchar *signal_name, + GVariant *parameters, gpointer user_data) +{ + int state = 0; + + g_variant_get(parameters, "(i)", &state); + + if (state != BT_DEVICED_POWEROFF_SIGNAL_POWEROFF && + state != BT_DEVICED_POWEROFF_SIGNAL_REBOOT) { + BT_DBG("Not interested event : %d", state); + return; + } + + if (_bt_adapter_get_status() == BT_ACTIVATING) { + BT_INFO("Just update VCONFKEY_BT_STATUS in Power off"); + if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_ON)) + BT_ERR("Set VCONFKEY_BT_STATUS failed"); + } else { + __bt_set_in_poweroff(); + } +} + +void _bt_service_register_poweroff_event(void) +{ + if (poweroff_subscribe_id) + return; + + poweroff_subscribe_id = g_dbus_connection_signal_subscribe( + _bt_gdbus_get_system_gconn(), NULL, + BT_DEVICED_POWEROFF_INTERFACE, + BT_DEVICED_POWEROFF_SIGNAL, + BT_DEVICED_POWEROFF_OBJECT_PATH, + NULL, 0, __bt_poweroff_event_filter, NULL, NULL); +} + +void _bt_service_unregister_poweroff_event(void) +{ + if (poweroff_subscribe_id == 0) + return; + + g_dbus_connection_signal_unsubscribe(_bt_gdbus_get_system_gconn(), + poweroff_subscribe_id); + poweroff_subscribe_id = 0; +} + void _bt_service_register_vconf_handler(void) { BT_DBG("+"); -#ifdef TIZEN_TELEPHONY_ENABLED +#ifdef TIZEN_FEATURE_FLIGHTMODE_ENABLED if (vconf_notify_key_changed(VCONFKEY_TELEPHONY_FLIGHT_MODE, (vconf_callback_fn)__bt_service_flight_ps_mode_cb, NULL) < 0) BT_ERR("Unable to register key handler"); @@ -740,45 +814,39 @@ void _bt_service_register_vconf_handler(void) BT_DBG("Telephony is disabled"); #endif -#ifndef TIZEN_WEARABLE -#ifdef ENABLE_TIZEN_2_4 +#ifndef TIZEN_PROFILE_WEARABLE if (vconf_notify_key_changed(VCONFKEY_SETAPPL_PSMODE, (vconf_callback_fn)__bt_service_flight_ps_mode_cb, NULL) < 0) BT_ERR("Unable to register key handler"); #endif -#endif } void _bt_service_unregister_vconf_handler(void) { BT_DBG("+"); -#ifdef TIZEN_TELEPHONY_ENABLED +#ifdef TIZEN_FEATURE_FLIGHTMODE_ENABLED vconf_ignore_key_changed(VCONFKEY_TELEPHONY_FLIGHT_MODE, (vconf_callback_fn)__bt_service_flight_ps_mode_cb); #endif -#ifndef TIZEN_WEARABLEi -#ifdef ENABLE_TIZEN_2_4 +#ifndef TIZEN_PROFILE_WEARABLE vconf_ignore_key_changed(VCONFKEY_SETAPPL_PSMODE, (vconf_callback_fn)__bt_service_flight_ps_mode_cb); #endif -#endif } static void __bt_state_event_handler(const char *event_name, bundle *data, void *user_data) { const char *bt_status = NULL; const char *bt_le_status = NULL; - const char *bt_transfering_status = NULL; BT_DBG("bt state set event(%s) received", event_name); -#ifdef ENABLE_TIZEN_2_4 + bt_status = bundle_get_val(data, EVT_KEY_BT_STATE); BT_DBG("bt_state: (%s)", bt_status); bt_le_status = bundle_get_val(data, EVT_KEY_BT_LE_STATE); BT_DBG("bt_state: (%s)", bt_le_status); -#endif } void _bt_handle_adapter_added(void) @@ -787,23 +855,34 @@ void _bt_handle_adapter_added(void) bt_status_t status; bt_le_status_t le_status; int ret; - +/* if (timer_id > 0) { BT_DBG("g_source is removed"); g_source_remove(timer_id); timer_id = 0; } +*/ status = _bt_adapter_get_status(); le_status = _bt_adapter_get_le_status(); - BT_DBG("status : %d", status); - BT_DBG("le_status : %d", le_status); + BT_INFO("status : %d", status); + BT_INFO("le_status : %d", le_status); +#ifndef USB_BLUETOOTH adapter_agent = _bt_create_agent(BT_ADAPTER_AGENT_PATH, TRUE); if (!adapter_agent) { BT_ERR("Fail to register agent"); return; } +#else + if (adapter_agent == NULL) { + adapter_agent = _bt_create_agent(BT_ADAPTER_AGENT_PATH, TRUE); + if (!adapter_agent) { + BT_ERR("Fail to register agent"); + return; + } + } +#endif if (_bt_register_media_player() != BLUETOOTH_ERROR_NONE) BT_ERR("Fail to register media player"); @@ -811,7 +890,7 @@ void _bt_handle_adapter_added(void) if (_bt_register_obex_server() != BLUETOOTH_ERROR_NONE) BT_ERR("Fail to init obex server"); -#ifdef TIZEN_BT_PAN_NAP_ENABLE +#ifdef TIZEN_BT_PAN_NAP_ENABLED if (_bt_network_activate() != BLUETOOTH_ERROR_NONE) BT_ERR("Fail to activate network"); #endif @@ -822,26 +901,22 @@ void _bt_handle_adapter_added(void) if (ret < 0) BT_ERR("Unable to register key handler"); - if (le_status == BT_LE_ACTIVATING) { + if (le_status == BT_LE_ACTIVATING || + status == BT_ACTIVATING) { __bt_set_le_enabled(); _bt_adapter_set_le_status(BT_LE_ACTIVATED); } + if (status == BT_ACTIVATING) { __bt_set_enabled(); _bt_adapter_set_status(BT_ACTIVATED); } -#ifdef ENABLE_TIZEN_2_4 - journal_bt_on(); -#endif - _bt_service_register_vconf_handler(); -#if 0 /* eventsystem */ if (eventsystem_register_event(SYS_EVENT_BT_STATE, &status_reg_id, (eventsystem_handler)__bt_state_event_handler, NULL) != ES_R_OK) { BT_ERR("Fail to register system event"); } -#endif } void _bt_handle_adapter_removed(void) @@ -849,33 +924,45 @@ void _bt_handle_adapter_removed(void) int ret; _bt_adapter_set_status(BT_DEACTIVATED); -#ifdef ENABLE_TIZEN_2_4 - journal_bt_off(); -#endif __bt_visibility_alarm_remove(); - if (visible_timer.alarm_init) { + if (alarm_mgr.is_alarm_initialized == TRUE) { alarmmgr_fini(); - visible_timer.alarm_init = FALSE; + alarm_mgr.is_alarm_initialized = FALSE; + g_list_free_full(alarm_mgr.g_alarm_list, alarm_data_free); + alarm_mgr.g_alarm_list = NULL; } +#ifdef TIZEN_BT_A2DP_SINK_AUTO_CONNECT + _bt_audio_stop_auto_connect(); +#endif + ret = vconf_ignore_key_changed(VCONFKEY_SETAPPL_DEVICE_NAME_STR, (vconf_callback_fn)__bt_phone_name_changed_cb); - if (0 != ret) { + if (0 != ret) ERR("vconf_ignore_key_changed failed\n"); - } +#ifndef USB_BLUETOOTH _bt_destroy_agent(adapter_agent); adapter_agent = NULL; - _bt_reliable_terminate_service(NULL); -#if 0 - if (eventsystem_unregister_event(status_reg_id) != ES_R_OK) { - BT_ERR("Fail to unregister system event"); + if (is_recovery_mode == TRUE) { + /* Send disabled event */ + _bt_set_disabled(BLUETOOTH_ERROR_NONE); + + /* Will recover BT by bt-core, so set the mode as activating */ + _bt_adapter_set_status(BT_ACTIVATING); + is_recovery_mode = FALSE; + } else { + _bt_reliable_terminate_service(NULL); } +#else + _bt_set_disabled(BLUETOOTH_ERROR_NONE); #endif + if (eventsystem_unregister_event(status_reg_id) != ES_R_OK) + BT_ERR("Fail to unregister system event"); } static gboolean __bt_enable_timeout_cb(gpointer user_data) @@ -914,10 +1001,11 @@ static gboolean __bt_enable_timeout_cb(gpointer user_data) } g_variant_unref(result); - _bt_set_disabled(BLUETOOTH_ERROR_TIMEOUT); +#ifndef USB_BLUETOOTH _bt_terminate_service(NULL); +#endif return FALSE; } @@ -957,7 +1045,6 @@ static gboolean __bt_enable_le_timeout_cb(gpointer user_data) } g_variant_unref(result); - _bt_adapter_set_le_status(BT_LE_DEACTIVATED); _bt_set_le_disabled(BLUETOOTH_ERROR_TIMEOUT); @@ -994,6 +1081,43 @@ void _bt_adapter_start_enable_timer(void) return; } +#ifdef TIZEN_TV +static gboolean __bt_adapter_enabled_cb(gpointer user_data) +{ + BT_DBG("+"); + + __bt_set_enabled(); + _bt_adapter_set_status(BT_ACTIVATED); + + return FALSE; +} +#endif + +int _bt_enable_adapter_check_status(void) +{ + bt_status_t status = _bt_adapter_get_status(); + bt_le_status_t le_status = _bt_adapter_get_le_status(); + + BT_DBG(""); + + if (status == BT_ACTIVATING) { + BT_ERR("Enabling in progress"); + return BLUETOOTH_ERROR_IN_PROGRESS; + } + + if (status == BT_ACTIVATED) { + BT_ERR("Already enabled"); + return BLUETOOTH_ERROR_DEVICE_ALREADY_ENABLED; + } + + if (status == BT_DEACTIVATING || le_status == BT_LE_DEACTIVATING) { + BT_ERR("Disabling in progress"); + return BLUETOOTH_ERROR_DEVICE_BUSY; + } + + return BLUETOOTH_ERROR_NONE; +} + int _bt_enable_adapter(void) { GDBusProxy *proxy; @@ -1022,6 +1146,29 @@ int _bt_enable_adapter(void) _bt_adapter_set_status(BT_ACTIVATING); +#ifdef TIZEN_TV +{ + int adapter_status = BT_ADAPTER_DISABLED; + + if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_OFF) != 0) + BT_ERR("Set vconf failed"); + + _bt_check_adapter(&adapter_status); + if (adapter_status == BT_ADAPTER_ENABLED) { + g_idle_add(__bt_adapter_enabled_cb, NULL); + _bt_adapter_start_enable_timer(); + return BLUETOOTH_ERROR_NONE; + } +} +#endif + + if (__bt_is_in_poweroff() == TRUE) { + BT_INFO("Just update VCONFKEY_BT_STATUS in Power off"); + if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_ON) != 0) + BT_ERR("Set VCONFKEY_BT_STATUS failed"); + return BLUETOOTH_ERROR_NONE; + } + proxy = __bt_get_core_proxy(); if (!proxy) return BLUETOOTH_ERROR_INTERNAL; @@ -1029,11 +1176,10 @@ int _bt_enable_adapter(void) if (le_status == BT_LE_ACTIVATED) { BT_INFO("LE Already enabled. Just turn on PSCAN"); ret = _bt_set_connectable(TRUE); - if (ret == BLUETOOTH_ERROR_NONE) { + if (ret == BLUETOOTH_ERROR_NONE) _bt_adapter_set_status(BT_ACTIVATED); - } else { + else return BLUETOOTH_ERROR_INTERNAL; - } } result = g_dbus_proxy_call_sync(proxy, "EnableAdapter", @@ -1041,8 +1187,8 @@ int _bt_enable_adapter(void) G_DBUS_CALL_FLAGS_NONE, BT_ENABLE_TIMEOUT, NULL, &error); if (error) { - BT_ERR("EnableAdapterLe failed: %s", error->message); - _bt_adapter_set_status(BT_DEACTIVATED); + BT_ERR("EnableAdapterLe failed: %s", error->message); + _bt_adapter_set_status(BT_DEACTIVATED); g_clear_error(&error); error = NULL; result = g_dbus_proxy_call_sync(proxy, @@ -1058,17 +1204,17 @@ int _bt_enable_adapter(void) g_clear_error(&error); } g_variant_unref(result); +#ifndef USB_BLUETOOTH /* Terminate myself */ g_idle_add((GSourceFunc)_bt_terminate_service, NULL); +#endif return BLUETOOTH_ERROR_INTERNAL; } g_variant_unref(result); - - if (le_status == BT_LE_ACTIVATED) { + if (le_status == BT_LE_ACTIVATED) __bt_set_enabled(); - } else { + else _bt_adapter_start_enable_timer(); - } return BLUETOOTH_ERROR_NONE; } @@ -1082,7 +1228,7 @@ static gboolean __bt_disconnect_all(void) GVariant *result; GError *error = NULL; GArray *device_list; - bluetooth_device_info_t info; + bluetooth_device_info_t *info; guint size; char *device_path = NULL; char address[BT_ADDRESS_STRING_SIZE] = { 0 }; @@ -1090,7 +1236,7 @@ static gboolean __bt_disconnect_all(void) BT_DBG(""); - conn = _bt_get_system_gconn(); + conn = _bt_gdbus_get_system_gconn(); device_list = g_array_new(FALSE, FALSE, sizeof(gchar)); @@ -1104,12 +1250,12 @@ static gboolean __bt_disconnect_all(void) for (i = 0; i < size; i++) { - info = g_array_index(device_list, + info = &g_array_index(device_list, bluetooth_device_info_t, i); - if (info.connected != BLUETOOTH_CONNECTED_LINK_NONE) { + if (info->connected != BLUETOOTH_CONNECTED_LINK_NONE) { BT_DBG("Found Connected device"); - _bt_convert_addr_type_to_string(address, info.device_address.addr); + _bt_convert_addr_type_to_string(address, info->device_address.addr); device_path = _bt_get_device_object_path(address); if (device_path == NULL) continue; @@ -1154,6 +1300,7 @@ static gboolean __bt_disconnect_all(void) return ret; } +#if 0 static gboolean __bt_set_disabled_timeout_cb(gpointer user_data) { BT_DBG(""); @@ -1161,17 +1308,21 @@ static gboolean __bt_set_disabled_timeout_cb(gpointer user_data) return FALSE; } +#endif -int __bt_disable_cb(void) +int _bt_disable_cb(void) { FN_START; GDBusProxy *proxy; - bt_le_status_t le_status; +#if 0 int ret; +#endif GVariant *result; GError *error = NULL; _bt_adapter_set_status(BT_DEACTIVATING); +#if 0 + bt_le_status_t le_status; le_status = _bt_adapter_get_le_status(); BT_DBG("le_status : %d", le_status); if (le_status == BT_LE_ACTIVATED) { @@ -1191,7 +1342,7 @@ int __bt_disable_cb(void) } } } - +#endif proxy = __bt_get_core_proxy(); retv_if(!proxy, BLUETOOTH_ERROR_INTERNAL); @@ -1214,6 +1365,24 @@ int __bt_disable_cb(void) } g_variant_unref(result); + return BLUETOOTH_ERROR_NONE; +} + +int _bt_disable_adapter_check_status(void) +{ + bt_status_t status = _bt_adapter_get_status(); + + BT_DBG(""); + + if (status == BT_DEACTIVATING) { + BT_DBG("Disabling in progress"); + return BLUETOOTH_ERROR_IN_PROGRESS; + } + + if (status == BT_DEACTIVATED) { + BT_DBG("Already disabled"); + return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED; + } return BLUETOOTH_ERROR_NONE; } @@ -1239,7 +1408,7 @@ int _bt_disable_adapter(void) } __bt_disconnect_all(); - ret = __bt_disable_cb(); + ret = _bt_disable_cb(); BT_DBG("-"); return ret; @@ -1253,12 +1422,12 @@ int _bt_recover_adapter(void) GError *error = NULL; if (_bt_adapter_get_status() == BT_DEACTIVATING) { - BT_DBG("Disabling in progress"); + BT_ERR("Disabling in progress"); return BLUETOOTH_ERROR_IN_PROGRESS; } if (_bt_adapter_get_status() == BT_DEACTIVATED) { - BT_DBG("Already disabled"); + BT_ERR("Already disabled"); return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED; } @@ -1284,6 +1453,8 @@ int _bt_recover_adapter(void) return BLUETOOTH_ERROR_INTERNAL; } + is_recovery_mode = TRUE; + g_variant_unref(result); __bt_disconnect_all(); @@ -1322,13 +1493,13 @@ int _bt_reset_adapter(void) g_variant_unref(result); /* Terminate myself */ - if (_bt_adapter_get_status() == BT_DEACTIVATED) { + if (_bt_adapter_get_status() == BT_DEACTIVATED) g_idle_add((GSourceFunc)_bt_terminate_service, NULL); - } return BLUETOOTH_ERROR_NONE; } +#ifndef TIZEN_TV int _bt_check_adapter(int *status) { @@ -1347,6 +1518,52 @@ int _bt_check_adapter(int *status) g_free(adapter_path); return BLUETOOTH_ERROR_NONE; } +#else +int _bt_check_adapter(int *status) +{ + GDBusProxy *proxy; + GError *error = NULL; + GVariant *result; + GVariant *temp; + gboolean powered = FALSE; + + BT_CHECK_PARAMETER(status, return); + + *status = BT_ADAPTER_DISABLED; + + proxy = _bt_get_adapter_properties_proxy(); + retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL); + + result = g_dbus_proxy_call_sync(proxy, + "Get", + g_variant_new("(ss)", BT_ADAPTER_INTERFACE, + "Powered"), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &error); + + if (!result) { + BT_ERR("Failed to get local address"); + if (error != NULL) { + BT_ERR("Failed to get local address (Error: %s)", error->message); + g_clear_error(&error); + } + return BLUETOOTH_ERROR_INTERNAL; + } + + g_variant_get(result, "(v)", &temp); + powered = g_variant_get_boolean(temp); + BT_DBG("powered: %d", powered); + + if (powered) + *status = BT_ADAPTER_ENABLED; + + g_variant_unref(result); + g_variant_unref(temp); + return BLUETOOTH_ERROR_NONE; +} +#endif int _bt_enable_adapter_le(void) { @@ -1467,7 +1684,6 @@ int _bt_disable_adapter_le(void) } g_variant_unref(result); - _bt_set_le_disabled(BLUETOOTH_ERROR_NONE); BT_DBG("le status : %d", _bt_adapter_get_le_status()); BT_DBG("-"); @@ -1510,11 +1726,10 @@ int _bt_get_local_address(bluetooth_device_address_t *local_address) address = g_variant_get_string(temp, NULL); BT_DBG("Address:%s", address); - if (address) { + if (address) _bt_convert_addr_string_to_type(local_address->addr, address); - } else { + else return BLUETOOTH_ERROR_INTERNAL; - } g_variant_unref(result); g_variant_unref(temp); @@ -1672,8 +1887,9 @@ int _bt_is_service_used(char *service_uuid, gboolean *used) GError *error = NULL; int ret = BLUETOOTH_ERROR_NONE; GVariant *result; - GVariantIter *iter; - gchar *uuid; + GVariant *temp = NULL; + GVariantIter *iter = NULL; + gchar *uuid = NULL; BT_DBG("+"); BT_CHECK_PARAMETER(service_uuid, return); @@ -1700,21 +1916,21 @@ int _bt_is_service_used(char *service_uuid, gboolean *used) return BLUETOOTH_ERROR_INTERNAL; } - g_variant_get(result, "as", &iter); - while (g_variant_iter_loop(iter, "s", &uuid)) { + g_variant_get(result, "(v)", &temp); + g_variant_get(temp, "as", &iter); + + *used = FALSE; + while (g_variant_iter_loop(iter, "&s", &uuid)) { if (strcasecmp(uuid, service_uuid) == 0) { *used = TRUE; - g_free(uuid); - goto done; + break; } } - - *used = FALSE; - -done: g_variant_iter_free(iter); g_variant_unref(result); + BT_DBG("Service Used? %d", *used); + return ret; } @@ -1744,7 +1960,7 @@ static gboolean __bt_get_discoverable_property(void) g_clear_error(&error); } else BT_ERR("Failed to get Discoverable property"); - return FALSE; + return BLUETOOTH_ERROR_INTERNAL; } g_variant_get(result, "(v)", &temp); @@ -1792,6 +2008,19 @@ int _bt_set_discoverable_mode(int discoverable_mode, int timeout) retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL); +#ifdef TIZEN_DPM_ENABLE + if (discoverable_mode != BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE && + _bt_dpm_get_bluetooth_limited_discoverable_state() == DPM_RESTRICTED) { + _bt_launch_dpm_popup("DPM_POLICY_DISABLE_BT_HANDSFREE"); + return BLUETOOTH_ERROR_ACCESS_DENIED; + } + if (discoverable_mode != BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE && + _bt_dpm_get_bluetooth_limited_discoverable_state() == DPM_RESTRICTED) { + _bt_launch_dpm_popup("DPM_POLICY_DISABLE_BT"); + return BLUETOOTH_ERROR_ACCESS_DENIED; + } +#endif + switch (discoverable_mode) { case BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE: pg_scan = TRUE; @@ -1990,12 +2219,19 @@ int _bt_cancel_discovery(void) &error); if (!result) { + int ret = BLUETOOTH_ERROR_INTERNAL; if (error != NULL) { BT_ERR("StopDiscovery failed (Error: %s)", error->message); + + if (g_strrstr(error->message, "No discovery started")) + ret = BLUETOOTH_ERROR_NOT_IN_OPERATION; + g_clear_error(&error); - } else + } else { BT_ERR("StopDiscovery failed"); - return BLUETOOTH_ERROR_INTERNAL; + } + + return ret; } cancel_by_user = TRUE; @@ -2082,7 +2318,7 @@ int _bt_set_connectable(gboolean is_connectable) return BLUETOOTH_ERROR_INTERNAL; } - BT_INFO("Set connectable [%d]", is_connectable); + BT_INFO_C("### Set connectable [%d]", is_connectable); g_variant_unref(result); return BLUETOOTH_ERROR_NONE; } @@ -2192,11 +2428,11 @@ static bluetooth_device_info_t *__bt_parse_device_info(GVariantIter *item_iter) address = g_variant_get_string(value, NULL); _bt_convert_addr_string_to_type(dev_info->device_address.addr, address); - } else if(!g_strcmp0(key, "Class")) { + } else if (!g_strcmp0(key, "Class")) { unsigned int cod; cod = g_variant_get_uint32(value); _bt_divide_device_class(&dev_info->device_class, cod); - } else if(!g_strcmp0(key, "Name")) { + } else if (!g_strcmp0(key, "Name")) { const char *name = NULL; name = g_variant_get_string(value, NULL); /* If there is no Alias */ @@ -2204,7 +2440,7 @@ static bluetooth_device_info_t *__bt_parse_device_info(GVariantIter *item_iter) g_strlcpy(dev_info->device_name.name, name, BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1); } - } else if(!g_strcmp0(key, "Alias")) { + } else if (!g_strcmp0(key, "Alias")) { const char *alias = NULL; alias = g_variant_get_string(value, NULL); /* Overwrite the name */ @@ -2214,6 +2450,8 @@ static bluetooth_device_info_t *__bt_parse_device_info(GVariantIter *item_iter) g_strlcpy(dev_info->device_name.name, alias, BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1); } + } else if (!g_strcmp0(key, "IsAliasSet")) { + dev_info->is_alias_set = g_variant_get_boolean(value); } else if (!g_strcmp0(key, "Connected")) { dev_info->connected = g_variant_get_byte(value); } else if (!g_strcmp0(key, "Paired")) { @@ -2246,18 +2484,17 @@ static bluetooth_device_info_t *__bt_parse_device_info(GVariantIter *item_iter) } dev_info->service_index = i; g_variant_iter_free(iter); - } else if (strcasecmp(key, "ManufacturerDataLen") == 0) { + } else if (strcasecmp(key, "LegacyManufacturerDataLen") == 0) { dev_info->manufacturer_data.data_len = g_variant_get_uint16(value); - } else if (strcasecmp(key, "ManufacturerData") == 0) { + } else if (strcasecmp(key, "LegacyManufacturerData") == 0) { manufacturer_data = g_byte_array_new(); g_variant_get(value, "ay", &char_value_iter); - while(g_variant_iter_loop(char_value_iter, "y", &char_value)) { + while (g_variant_iter_loop(char_value_iter, "y", &char_value)) g_byte_array_append(manufacturer_data, &char_value, 1); - } + if (manufacturer_data) { - if (manufacturer_data->len > 0) { + if (manufacturer_data->len > 0) memcpy(dev_info->manufacturer_data.data, manufacturer_data->data, manufacturer_data->len); - } } g_variant_iter_free(char_value_iter); g_byte_array_free(manufacturer_data, TRUE); @@ -2313,7 +2550,7 @@ int _bt_get_bonded_devices(GArray **dev_list) GVariantIter *iter = NULL; GError *error = NULL; - conn = _bt_get_system_conn(); + conn = _bt_gdbus_get_system_gconn(); retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL); manager_proxy = _bt_get_manager_proxy(); @@ -2346,6 +2583,114 @@ int _bt_get_bonded_devices(GArray **dev_list) return BLUETOOTH_ERROR_NONE; } +int _bt_get_profile_connected_devices(char *profile_uuid, GArray **addr_list) +{ + BT_DBG("+"); + 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; + + conn = _bt_gdbus_get_system_gconn(); + retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL); + + manager_proxy = _bt_get_manager_proxy(); + retv_if(manager_proxy == NULL, BLUETOOTH_ERROR_INTERNAL); + + result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects", + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + NULL); + + if (!result) { + if (error != NULL) { + BT_ERR("Failed to GetManagedObjects (Error: %s)", error->message); + g_clear_error(&error); + error = NULL; + } else + BT_ERR("Failed to Failed to GetManagedObjects"); + return BLUETOOTH_ERROR_INTERNAL; + } + + /* 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) { + BT_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_BLUEZ_NAME, + object_path, BT_DEVICE_INTERFACE, NULL, NULL); + + if (device_proxy == NULL) { + BT_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) { + BT_ERR("Error occured in Proxy call"); + if (error) { + BT_ERR("Error occured in Proxy call [%s]\n", 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_ADDRESS_STRING_SIZE]; + bluetooth_device_address_t *addr = NULL; + + _bt_convert_device_path_to_address(object_path, address); + + addr = g_malloc0(sizeof(bluetooth_device_address_t)); + _bt_convert_addr_string_to_type(addr->addr, address); + + g_array_append_vals(*addr_list, addr, + sizeof(bluetooth_device_address_t)); + } + + g_variant_unref(result1); + g_object_unref(device_proxy); + + break; + } + } + } + + g_variant_unref(result); + g_variant_iter_free(iter); + + BT_DBG("-"); + return BLUETOOTH_ERROR_NONE; +} + int _bt_get_bonded_device_info(bluetooth_device_address_t *device_address, bluetooth_device_info_t *dev_info) { @@ -2372,6 +2717,75 @@ int _bt_get_bonded_device_info(bluetooth_device_address_t *device_address, return ret; } +int _bt_is_alias_set(bluetooth_device_address_t *device_address, gboolean *is_alias_set) +{ + char *object_path = NULL; + char address[BT_ADDRESS_STRING_SIZE] = { 0 }; + gboolean alias_set = FALSE; + + GDBusConnection *conn; + GDBusProxy *device_proxy; + GError *error = NULL; + GVariant *result = NULL; + GVariant *temp = NULL; + + + BT_CHECK_PARAMETER(device_address, return); + BT_CHECK_PARAMETER(is_alias_set, return); + + _bt_convert_addr_type_to_string(address, device_address->addr); + + object_path = _bt_get_device_object_path(address); + retv_if(object_path == NULL, BLUETOOTH_ERROR_NOT_PAIRED); + + conn = _bt_gdbus_get_system_gconn(); + if (conn == NULL) { + g_free(object_path); + return BLUETOOTH_ERROR_INTERNAL; + } + + device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE, + NULL, + BT_BLUEZ_NAME, + object_path, + BT_PROPERTIES_INTERFACE, + NULL, NULL); + if (device_proxy == NULL) { + g_free(object_path); + return BLUETOOTH_ERROR_INTERNAL; + } + + result = g_dbus_proxy_call_sync(device_proxy, "Get", + g_variant_new("(ss)", BT_DEVICE_INTERFACE, "IsAliasSet"), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &error); + + if (!result) { + BT_ERR("Error occured in Proxy call"); + if (error != NULL) { + BT_ERR("Getting is_alias_set property failed: [%s]\n", error->message); + g_error_free(error); + } + g_object_unref(device_proxy); + g_free(object_path); + return BLUETOOTH_ERROR_INTERNAL; + } + + g_variant_get(result, "(v)", &temp); + alias_set = g_variant_get_boolean(temp); + *is_alias_set = alias_set; + BT_DBG("address: [%s] | *is_alias_set: %s", address, *is_alias_set ? "TRUE" : "FALSE"); + g_variant_unref(temp); + g_variant_unref(result); + g_object_unref(device_proxy); + + g_free(object_path); + + return BLUETOOTH_ERROR_NONE; +} + int _bt_get_timeout_value(int *timeout) { time_t current_time; @@ -2429,6 +2843,47 @@ int _bt_set_le_privacy(gboolean set_privacy) return BLUETOOTH_ERROR_NONE; } +int _bt_set_le_static_random_address(gboolean is_enable) +{ + GDBusProxy *proxy; + GError *error = NULL; + GVariant *result = NULL; + + if (__bt_is_factory_test_mode()) { + BT_ERR("Unable to set le random address in factory binary !!"); + return BLUETOOTH_ERROR_NOT_SUPPORT; + } + + if (_bt_adapter_get_status() != BT_ACTIVATED && + _bt_adapter_get_le_status() != BT_LE_ACTIVATED) { + return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED; + } + + proxy = _bt_get_adapter_proxy(); + retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL); + + result = g_dbus_proxy_call_sync(proxy, + "SetLeStaticRandomAddress", + g_variant_new("(b)", is_enable), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &error); + + if (!result) { + if (error != NULL) { + BT_ERR("Failed to SetLeStaticRandomAddress (Error: %s)", error->message); + g_clear_error(&error); + } else + BT_ERR("Failed to SetLeStaticRandomAddress"); + return BLUETOOTH_ERROR_INTERNAL; + } + + g_variant_unref(result); + BT_INFO("SetLeStaticRandomAddress as %d", is_enable); + return BLUETOOTH_ERROR_NONE; +} + int _bt_set_manufacturer_data(bluetooth_manufacturer_data_t *m_data) { GDBusProxy *proxy; @@ -2450,9 +2905,8 @@ int _bt_set_manufacturer_data(bluetooth_manufacturer_data_t *m_data) builder = g_variant_builder_new(G_VARIANT_TYPE("ay")); - for (i = 0; i < (m_data->data_len) + 2; i++) { + 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); @@ -2475,9 +2929,8 @@ int _bt_set_manufacturer_data(bluetooth_manufacturer_data_t *m_data) } builder = g_variant_builder_new(G_VARIANT_TYPE("ay")); - for (i = 0; i < (m_data->data_len) + 2; i++) { + 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); @@ -2493,3 +2946,182 @@ int _bt_set_manufacturer_data(bluetooth_manufacturer_data_t *m_data) return BLUETOOTH_ERROR_NONE; } + +int _bt_service_set_alarm(int timeout, bt_set_alarm_cb call_back, void *user_data, alarm_id_t *alarm_id) +{ + int result = BLUETOOTH_ERROR_NONE; + bt_service_alarm_t *alarm = NULL; + + if (!call_back || !alarm_id) + return BLUETOOTH_ERROR_INVALID_PARAM; + + if (!alarm_mgr.is_alarm_initialized) { + result = alarmmgr_init("bt-service"); + if (result != 0) { + BT_ERR("Failed to initialize alarm = %d", result); + result = BLUETOOTH_ERROR_INTERNAL; + goto finish; + } + result = alarmmgr_set_cb(alarm_cb, NULL); + if (result != 0) { + BT_ERR("Failed to set the callback = %d", result); + result = BLUETOOTH_ERROR_INTERNAL; + goto finish; + } + alarm_mgr.is_alarm_initialized = TRUE; + } + + alarm = g_malloc0(sizeof(bt_service_alarm_t)); + if (!alarm) + return BLUETOOTH_ERROR_MEMORY_ALLOCATION; + + result = alarmmgr_add_alarm(ALARM_TYPE_VOLATILE, timeout, + 0, NULL, alarm_id); + if (result != 0) { + BT_ERR("Failed to create alarm error = %d", result); + result = BLUETOOTH_ERROR_INTERNAL; + g_free(alarm); + goto finish; + } + alarm->alarm_id = *alarm_id; + alarm->callback = call_back; + alarm->user_data = user_data; + + alarm_mgr.g_alarm_list = g_list_append(alarm_mgr.g_alarm_list, alarm); + result = BLUETOOTH_ERROR_NONE; +finish: + return result; +} + +static int alarm_cb(alarm_id_t alarm_id, void* user_param) +{ + GList *node = NULL; + bt_service_alarm_t *p_data; + bt_set_alarm_cb callback = NULL; + void *user_data = NULL; + + node = g_list_find_custom(alarm_mgr.g_alarm_list, + GINT_TO_POINTER(alarm_id), compare_alarm); + if (!node) + return 0; + + p_data = (bt_service_alarm_t *)node->data; + alarm_mgr.g_alarm_list = g_list_delete_link(alarm_mgr.g_alarm_list, + node); + + if (!p_data) + return 0; + + callback = p_data->callback; + user_data = p_data->user_data; + g_free(p_data); + + if (callback) + callback(alarm_id, user_data); + + return 0; +} + +int _bt_service_remove_alarm(alarm_id_t alarm_id) +{ + GList *list = NULL; + bt_service_alarm_t *p_data; + list = g_list_find_custom(alarm_mgr.g_alarm_list, GINT_TO_POINTER(alarm_id), compare_alarm); + + if (list != NULL) { + alarmmgr_remove_alarm(alarm_id); + p_data = (bt_service_alarm_t *)list->data; + alarm_mgr.g_alarm_list = g_list_remove(alarm_mgr.g_alarm_list, list->data); + g_free(p_data); + } + + return 0; +} + +gint compare_alarm(gconstpointer list_data, gconstpointer data) +{ + alarm_id_t alarm_id = (alarm_id_t)data; + bt_service_alarm_t *p_data = (bt_service_alarm_t *)list_data; + + if (p_data->alarm_id == alarm_id) + return 0; + + return 1; +} + +static void alarm_data_free(void *data) +{ + bt_service_alarm_t *p_data = (bt_service_alarm_t *)data; + g_free(p_data); + return; +} + +static gboolean _bt_adapter_request_delayed_cb(gpointer user_data) +{ + int result; + int function = (int)user_data; + + switch (function) { + case BT_ENABLE_ADAPTER: + result = _bt_enable_adapter(); + if (result != BLUETOOTH_ERROR_NONE) { + BT_ERR("_bt_enable_adapter is failed"); + /* Send enabled event to API */ + _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_ENABLED, + g_variant_new("(i)", result)); + } + break; + case BT_DISABLE_ADAPTER: + result = _bt_disable_adapter(); + if (result != BLUETOOTH_ERROR_NONE) { + BT_ERR("_bt_disable_adapter is failed"); + /* Send disabled event to API */ + _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_DISABLED, + g_variant_new("(i)", result)); + } + break; + default: + BT_ERR("function is NOT matched"); + break; + } + + return FALSE; +} + +int _bt_adapter_request_delayed(int function) +{ + int ret; + + switch (function) { + case BT_ENABLE_ADAPTER: + ret = _bt_enable_adapter_check_status(); + if (ret == BLUETOOTH_ERROR_NONE) + _bt_adapter_set_status(BT_ACTIVATING); + else + return ret; + + break; + case BT_DISABLE_ADAPTER: + ret = _bt_disable_adapter_check_status(); + if (ret == BLUETOOTH_ERROR_NONE) + _bt_adapter_set_status(BT_DEACTIVATING); + else + return ret; + + break; + default: + BT_ERR("function is NOT matched"); + return BLUETOOTH_ERROR_INTERNAL; + } + + g_idle_add((GSourceFunc)_bt_adapter_request_delayed_cb, (void*)function); + + return BLUETOOTH_ERROR_NONE; +} + + +int _bt_get_enable_timer_id(void) +{ + return timer_id; +} +