X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=bt-service%2Fbt-service-adapter.c;h=cf792103d3c47238155fa31beaed0f1cf8a4acd4;hb=f8cd843634b70ab96c83bd552606c197fcf5decc;hp=3f510adaa8ab25ce3a98bce3f79cd5bd403f5786;hpb=057d7a8c4d86274a4ac4a76c4f5a645d5674ddad;p=platform%2Fcore%2Fconnectivity%2Fbluetooth-frwk.git diff --git a/bt-service/bt-service-adapter.c b/bt-service/bt-service-adapter.c old mode 100644 new mode 100755 index 3f510ad..cf79210 --- a/bt-service/bt-service-adapter.c +++ b/bt-service/bt-service-adapter.c @@ -1,13 +1,17 @@ /* - * bluetooth-frwk + * Bluetooth-frwk * - * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Hocheol Seo + * Girishashok Joshi + * Chanyeol Park * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -24,13 +28,11 @@ #include #include #include -#include -#if !defined(LIBNOTIFY_SUPPORT) && !defined(LIBNOTIFICATION_SUPPORT) #include -#endif -#ifdef __TIZEN_MOBILE__ #include -#endif +#include +//#include + #include "alarm.h" #include "bluetooth-api.h" @@ -50,20 +52,72 @@ 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; +bt_adapter_timer_t visible_timer = {0, }; + static gboolean is_discovering; +static gboolean is_le_discovering; +static bt_le_discovery_type_t le_discovery_type = BT_LE_PASSIVE_SCAN; 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 void *adapter_agent = NULL; static DBusGProxy *core_proxy = NULL; +static guint timer_id = 0; +static guint le_timer_id = 0; #define BT_CORE_NAME "org.projectx.bt_core" #define BT_CORE_PATH "/org/projectx/bt_core" #define BT_CORE_INTERFACE "org.projectx.btcore" +#define BT_DISABLE_TIME 500 /* 500 ms */ + +DBusGProxy *_bt_init_core_proxy(void) +{ + DBusGProxy *proxy; + DBusGConnection *conn; + + conn = _bt_get_system_gconn(); + if (!conn) + return NULL; + + proxy = dbus_g_proxy_new_for_name(conn, BT_CORE_NAME, + BT_CORE_PATH, BT_CORE_INTERFACE); + if (!proxy) + return NULL; + + core_proxy = proxy; + + return proxy; +} + +static DBusGProxy *__bt_get_core_proxy(void) +{ + 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 !!"); + return TRUE; + } + + return FALSE; +} + static gboolean __bt_timeout_handler(gpointer user_data) { int result = BLUETOOTH_ERROR_NONE; @@ -86,8 +140,10 @@ static gboolean __bt_timeout_handler(gpointer user_data) visible_timer.event_id = 0; visible_timer.timeout = 0; +#ifndef TIZEN_WEARABLE if (vconf_set_int(BT_FILE_VISIBLE_TIME, 0) != 0) - BT_DBG("Set vconf failed\n"); + BT_ERR("Set vconf failed\n"); +#endif return FALSE; } @@ -96,12 +152,32 @@ 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 \n"); + BT_DBG("__bt_visibility_alarm_cb - alram id = [%d] \n", alarm_id); + + int result = BLUETOOTH_ERROR_NONE; + int timeout = 0; + + if (alarm_id != visible_timer.alarm_id) + return 0; + + if (visible_timer.event_id) { + _bt_send_event(BT_ADAPTER_EVENT, + BLUETOOTH_EVENT_DISCOVERABLE_TIMEOUT_CHANGED, + DBUS_TYPE_INT32, &result, + DBUS_TYPE_INT16, &timeout, + DBUS_TYPE_INVALID); + g_source_remove(visible_timer.event_id); + visible_timer.event_id = 0; + visible_timer.timeout = 0; +#ifndef TIZEN_WEARABLE + if (vconf_set_int(BT_FILE_VISIBLE_TIME, 0) != 0) + BT_ERR("Set vconf failed\n"); +#endif + } /* Switch Off visibility in Bluez */ _bt_set_discoverable_mode(BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE, 0); visible_timer.alarm_id = 0; - alarmmgr_fini(); return 0; } @@ -113,18 +189,15 @@ static void __bt_visibility_alarm_create() result = alarmmgr_add_alarm(ALARM_TYPE_VOLATILE, visible_timer.timeout, 0, NULL, &alarm_id); if(result < 0) { - BT_DBG("Failed to create alarm error = %d\n", result); - alarmmgr_fini(); + 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; } } -int __bt_set_visible_time(int timeout) +static void __bt_visibility_alarm_remove() { - int result; - if (visible_timer.event_id > 0) { g_source_remove(visible_timer.event_id); visible_timer.event_id = 0; @@ -134,29 +207,41 @@ int __bt_set_visible_time(int timeout) alarmmgr_remove_alarm(visible_timer.alarm_id); visible_timer.alarm_id = 0; } +} + +int __bt_set_visible_time(int timeout) +{ + int result; + + __bt_visibility_alarm_remove(); visible_timer.timeout = timeout; +#ifndef TIZEN_WEARABLE if (vconf_set_int(BT_FILE_VISIBLE_TIME, timeout) != 0) - BT_ERR("Set vconf failed\n"); - + BT_ERR("Set vconf failed"); +#endif if (timeout <= 0) return BLUETOOTH_ERROR_NONE; - /* Take start time */ - time(&(visible_timer.start_time)); - visible_timer.event_id = g_timeout_add_seconds(1, - __bt_timeout_handler, NULL); + if (!visible_timer.alarm_init) { + /* Set Alarm timer to switch off BT */ + result = alarmmgr_init("bt-service"); + if (result != 0) + return BLUETOOTH_ERROR_INTERNAL; - /* Set Alarm timer to switch off BT */ - result = alarmmgr_init("bt-service"); - if (result != 0) - return BLUETOOTH_ERROR_INTERNAL; + visible_timer.alarm_init = TRUE; + } result = alarmmgr_set_cb(__bt_visibility_alarm_cb, NULL); if (result != 0) return BLUETOOTH_ERROR_INTERNAL; + /* 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; @@ -191,227 +276,6 @@ static void __bt_get_service_list(GValue *value, bluetooth_device_info_t *dev) } } -static bt_remote_dev_info_t *__bt_parse_remote_device_info( - DBusMessageIter *item_iter) -{ - DBusMessageIter value_iter; - bt_remote_dev_info_t *dev_info; - - dbus_message_iter_recurse(item_iter, &value_iter); - - if (dbus_message_iter_get_arg_type(&value_iter) != - DBUS_TYPE_DICT_ENTRY) { - BT_DBG("No entry"); - return NULL; - } - - dev_info = g_malloc0(sizeof(bt_remote_dev_info_t)); - - while (dbus_message_iter_get_arg_type(&value_iter) == - DBUS_TYPE_DICT_ENTRY) { - char *value = NULL; - char *key; - DBusMessageIter dict_entry; - DBusMessageIter iter_dict_val; - - dbus_message_iter_recurse(&value_iter, &dict_entry); - - dbus_message_iter_get_basic(&dict_entry, &key); - - if (key == NULL) { - dbus_message_iter_next(&value_iter); - continue; - } - - if (!dbus_message_iter_next(&dict_entry)) { - dbus_message_iter_next(&value_iter); - continue; - } - dbus_message_iter_recurse(&dict_entry, &iter_dict_val); - - if (strcasecmp(key, "Address") == 0) { - const char *address = NULL; - dbus_message_iter_get_basic(&iter_dict_val, - &address); - dev_info->address = g_strdup(address); - } else if (strcasecmp(key, "Class") == 0) { - dbus_message_iter_get_basic(&iter_dict_val, - &dev_info->class); - } else if (strcasecmp(key, "Name") == 0) { - dbus_message_iter_get_basic(&iter_dict_val, - &value); - if (dev_info->name == NULL) - dev_info->name = g_strdup(value); - } else if (strcasecmp(key, "Connected") == 0) { - dbus_message_iter_get_basic(&iter_dict_val, - &dev_info->connected); - } else if (strcasecmp(key, "Paired") == 0) { - dbus_message_iter_get_basic(&iter_dict_val, - &dev_info->paired); - } else if (strcasecmp(key, "Trusted") == 0) { - dbus_message_iter_get_basic(&iter_dict_val, - &dev_info->trust); - } else if (strcasecmp(key, "RSSI") == 0) { - dbus_message_iter_get_basic(&iter_dict_val, - &dev_info->rssi); - } else if (strcasecmp(key, "UUIDs") == 0) { - DBusMessageIter uuid_iter; - DBusMessageIter tmp_iter; - int i = 0; - - dbus_message_iter_recurse(&iter_dict_val, - &uuid_iter); - tmp_iter = uuid_iter; - - /* Store the uuid count */ - while (dbus_message_iter_get_arg_type(&tmp_iter) != - DBUS_TYPE_INVALID) { - - dbus_message_iter_get_basic(&tmp_iter, - &value); - - dev_info->uuid_count++; - if (!dbus_message_iter_next(&tmp_iter)) - break; - } - - /* Store the uuids */ - if (dev_info->uuid_count > 0) { - dev_info->uuids = g_new0(char *, - dev_info->uuid_count + 1); - } else { - dbus_message_iter_next(&value_iter); - continue; - } - - while (dbus_message_iter_get_arg_type(&uuid_iter) != - DBUS_TYPE_INVALID) { - dbus_message_iter_get_basic(&uuid_iter, - &value); - dev_info->uuids[i] = g_strdup(value); - i++; - if (!dbus_message_iter_next(&uuid_iter)) { - break; - } - } - } - - dbus_message_iter_next(&value_iter); - } - - return dev_info; -} - -static void __bt_extract_remote_devinfo(DBusMessageIter *msg_iter, - GArray **dev_list) -{ - bt_remote_dev_info_t *dev_info = NULL; - char *object_path = NULL; - DBusMessageIter value_iter; - - /* Parse the signature: oa{sa{sv}}} */ - ret_if(dbus_message_iter_get_arg_type(msg_iter) != - DBUS_TYPE_OBJECT_PATH); - - dbus_message_iter_get_basic(msg_iter, &object_path); - ret_if(object_path == NULL); - - /* object array (oa) */ - ret_if(dbus_message_iter_next(msg_iter) == FALSE); - ret_if(dbus_message_iter_get_arg_type(msg_iter) != DBUS_TYPE_ARRAY); - - dbus_message_iter_recurse(msg_iter, &value_iter); - - /* string array (sa) */ - while (dbus_message_iter_get_arg_type(&value_iter) == - DBUS_TYPE_DICT_ENTRY) { - char *interface_name = NULL; - DBusMessageIter interface_iter; - - dbus_message_iter_recurse(&value_iter, &interface_iter); - - ret_if(dbus_message_iter_get_arg_type(&interface_iter) != - DBUS_TYPE_STRING); - - dbus_message_iter_get_basic(&interface_iter, &interface_name); - - ret_if(dbus_message_iter_next(&interface_iter) == FALSE); - - ret_if(dbus_message_iter_get_arg_type(&interface_iter) != - DBUS_TYPE_ARRAY); - - if (g_strcmp0(interface_name, "org.bluez.Device1") == 0) { - BT_DBG("Found a device: %s", object_path); - dev_info = __bt_parse_remote_device_info( - &interface_iter); - - if (dev_info) { - g_array_append_vals(*dev_list, dev_info, - sizeof(bt_remote_dev_info_t)); - } - } - - dbus_message_iter_next(&value_iter); - } -} - -int _bt_get_remote_found_devices(GArray **dev_list) -{ - DBusMessage *msg; - DBusMessage *reply; - DBusMessageIter reply_iter; - DBusMessageIter value_iter; - DBusError err; - DBusConnection *conn; - - conn = _bt_get_system_conn(); - retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL); - - msg = dbus_message_new_method_call(BT_BLUEZ_NAME, BT_MANAGER_PATH, - BT_MANAGER_INTERFACE, - "GetManagedObjects"); - - retv_if(msg == NULL, BLUETOOTH_ERROR_INTERNAL); - - /* Synchronous call */ - dbus_error_init(&err); - reply = dbus_connection_send_with_reply_and_block( - conn, msg, - -1, &err); - dbus_message_unref(msg); - - if (!reply) { - BT_ERR("Can't get managed objects"); - - if (dbus_error_is_set(&err)) { - BT_ERR("%s", err.message); - dbus_error_free(&err); - } - return BLUETOOTH_ERROR_INTERNAL; - } - - if (dbus_message_iter_init(reply, &reply_iter) == FALSE) { - BT_ERR("Fail to iterate the reply"); - return BLUETOOTH_ERROR_INTERNAL; - } - - dbus_message_iter_recurse(&reply_iter, &value_iter); - - /* signature of GetManagedObjects: a{oa{sa{sv}}} */ - while (dbus_message_iter_get_arg_type(&value_iter) == - DBUS_TYPE_DICT_ENTRY) { - DBusMessageIter msg_iter; - - dbus_message_iter_recurse(&value_iter, &msg_iter); - - __bt_extract_remote_devinfo(&msg_iter, dev_list); - - dbus_message_iter_next(&value_iter); - } - - return BLUETOOTH_ERROR_NONE; -} - static int __bt_get_bonded_device_info(gchar *device_path, bluetooth_device_info_t *dev_info) { @@ -425,6 +289,7 @@ static int __bt_get_bonded_device_info(gchar *device_path, gboolean trust; gboolean paired; gboolean connected; + GByteArray *manufacturer_data = NULL; GHashTable *hash = NULL; int ret; DBusGConnection *conn; @@ -442,7 +307,7 @@ static int __bt_get_bonded_device_info(gchar *device_path, dbus_g_proxy_call(device_proxy, "GetAll", &err, G_TYPE_STRING, BT_DEVICE_INTERFACE, - G_TYPE_INVALID, + G_TYPE_INVALID, dbus_g_type_get_map("GHashTable", G_TYPE_STRING, G_TYPE_VALUE), &hash, G_TYPE_INVALID); @@ -480,6 +345,9 @@ static int __bt_get_bonded_device_info(gchar *device_path, value = g_hash_table_lookup(hash, "Trusted"); trust = value ? g_value_get_boolean(value) : FALSE; + BT_DBG("paired: %d", paired); + BT_DBG("trust: %d", trust); + if ((paired == FALSE) && (trust == FALSE)) { return BLUETOOTH_ERROR_NOT_PAIRED; } @@ -490,10 +358,22 @@ static int __bt_get_bonded_device_info(gchar *device_path, value = g_hash_table_lookup(hash, "UUIDs"); __bt_get_service_list(value, dev_info); - _bt_convert_addr_string_to_type(dev_info->device_address.addr, - address); + value = g_hash_table_lookup(hash, "ManufacturerDataLen"); + dev_info->manufacturer_data.data_len = value ? g_value_get_uint(value) : 0; - _bt_divide_device_class(&dev_info->device_class, cod); + value = g_hash_table_lookup(hash, "ManufacturerData"); + manufacturer_data = value ? g_value_get_boxed(value) : NULL; + if (manufacturer_data) { + if (manufacturer_data->len > 0) { + BT_DBG("manufacturer_data->len = %d", manufacturer_data->len); + memcpy(dev_info->manufacturer_data.data, manufacturer_data->data, manufacturer_data->len); + } + } + + _bt_convert_addr_string_to_type(dev_info->device_address.addr, + address); + + _bt_divide_device_class(&dev_info->device_class, cod); g_strlcpy(dev_info->device_name.name, name, BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1); @@ -517,83 +397,34 @@ void _bt_set_discovery_status(gboolean mode) is_discovering = mode; } -void _bt_set_cancel_by_user(gboolean value) +void _bt_set_le_discovery_status(gboolean mode) { - cancel_by_user = value; + is_le_discovering = mode; } -gboolean _bt_get_cancel_by_user(void) +void _bt_set_le_discovery_type(bt_le_discovery_type_t type) { - return cancel_by_user; + le_discovery_type = type; } -static void __bt_flight_mode_cb(keynode_t *node, void *data) +bt_le_discovery_type_t _bt_get_le_discovery_type(void) { - gboolean flight_mode = FALSE; - int bt_status; - - BT_DBG("key=%s\n", vconf_keynode_get_name(node)); - - bt_status = _bt_adapter_get_status(); - - if (vconf_keynode_get_type(node) == VCONF_TYPE_BOOL) { - flight_mode = vconf_keynode_get_bool(node); - - BT_DBG("value=%d\n", flight_mode); - - if (flight_mode == TRUE) { - BT_DBG("Deactivate Bluetooth Service\n"); - if (vconf_set_int(BT_OFF_DUE_TO_FLIGHT_MODE, 1) != 0) - BT_DBG("Set vconf failed+\n"); - - if (bt_status == BT_ACTIVATED) - _bt_disable_adapter(); - } else { - - int value = 0; - - if (vconf_get_int(BT_OFF_DUE_TO_FLIGHT_MODE, &value)) - BT_ERR("Fail get flight mode value"); - - if (value == 0) - return; - - BT_DBG("Activate Bluetooth Service\n"); - if (vconf_set_int(BT_OFF_DUE_TO_FLIGHT_MODE, 0)) - BT_DBG("Set vconf failed\n"); - - if (bt_status == BT_DEACTIVATED) - _bt_enable_adapter(); - } - } + return le_discovery_type; } -#ifdef __TIZEN_MOBILE__ -static void __launch_bt_service(int status, int run_type) +void _bt_set_cancel_by_user(gboolean value) { - bundle *kb; - char status_val[5] = { 0, }; - char run_type_val[5] = { 0, }; - - snprintf(status_val, sizeof(status_val), "%d", status); - snprintf(run_type_val, sizeof(run_type_val), "%d", run_type); - - BT_DBG("status: %s, run_type: %s", status_val, run_type_val); - - kb = bundle_create(); - - bundle_add(kb, "launch-type", "setstate"); - bundle_add(kb, "status", status_val); - bundle_add(kb, "run-type", run_type_val); - - aul_launch_app("com.samsung.bluetooth", kb); + cancel_by_user = value; +} - bundle_free(kb); +gboolean _bt_get_cancel_by_user(void) +{ + return cancel_by_user; } -#endif void _bt_adapter_set_status(bt_status_t status) { + BT_INFO("adapter_status changed [%d] -> [%d]", adapter_status, status); adapter_status = status; } @@ -602,6 +433,17 @@ bt_status_t _bt_adapter_get_status(void) return adapter_status; } +void _bt_adapter_set_le_status(bt_le_status_t status) +{ + BT_INFO("adapter_le_status changed [%d] -> [%d]", adapter_le_status, status); + adapter_le_status = status; +} + +bt_le_status_t _bt_adapter_get_le_status(void) +{ + return adapter_le_status; +} + static void __bt_phone_name_changed_cb(keynode_t *node, void *data) { char *phone_name = NULL; @@ -612,6 +454,7 @@ static void __bt_phone_name_changed_cb(keynode_t *node, void *data) if (vconf_keynode_get_type(node) == VCONF_TYPE_STRING) { phone_name = vconf_keynode_get_str(node); + if (phone_name && strlen(phone_name) != 0) { if (!g_utf8_validate(phone_name, -1, (const char **)&ptr)) @@ -622,23 +465,60 @@ static void __bt_phone_name_changed_cb(keynode_t *node, void *data) } } +#ifdef TIZEN_WEARABLE +static char * __bt_change_dev_name(const char *default_name) +{ + FILE *fp = NULL; + char *buf = NULL; + char *name = NULL; + int result; + + if ((fp = fopen("/csa/bluetooth/.bd_addr", "r")) == NULL) { + BT_ERR("Unable to open bd_addr"); + return NULL; + } + + result = fseek(fp, -4, SEEK_END); + if (result < 0) { + BT_ERR("fseek is failed"); + fclose(fp); + return NULL; + } + + buf = (char *)malloc(sizeof(char) * 5); + if (buf == NULL) { + BT_ERR("malloc is failed"); + fclose(fp); + return NULL; + } + memset(buf, 0, 5); + + result = fread(buf, 1, 4, fp); + if (result) + BT_DBG("Size Read: [%d]", result); + else + BT_ERR("Error reading file: code[%d]", result); + + name = g_strdup_printf("%s (%s)", default_name, buf); + + BT_INFO("%s", name); + + free(buf); + fclose(fp); + + return name ; +} +#else static void __bt_set_visible_mode(void) { - int timeout; + int timeout = 0; if (vconf_get_int(BT_FILE_VISIBLE_TIME, &timeout) != 0) BT_ERR("Fail to get the timeout value"); /* -1: Always on */ - 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) { @@ -653,24 +533,36 @@ static void __bt_set_local_name(void) if (strlen(phone_name) != 0) { if (!g_utf8_validate(phone_name, -1, (const char **)&ptr)) *ptr = '\0'; + +#ifdef TIZEN_WEARABLE + if (strstr(phone_name, "(") == NULL) { + char *tmp = __bt_change_dev_name(phone_name); + if (tmp != NULL) { + free(phone_name); + phone_name = tmp; + } + } +#endif _bt_set_local_name(phone_name); } free(phone_name); } -void _bt_set_enabled(void) +static int __bt_set_enabled(void) { + int adapter_status = BT_ADAPTER_DISABLED; int result = BLUETOOTH_ERROR_NONE; - _bt_adapter_set_status(BT_ACTIVATED); + _bt_check_adapter(&adapter_status); - // register agent if it was not previously done. - if (!adapter_agent) { - BT_DBG(""); - _bt_handle_adapter_added(); + if (adapter_status == BT_ADAPTER_DISABLED) { + BT_ERR("Bluetoothd is not running"); + return BLUETOOTH_ERROR_INTERNAL; } +#ifndef TIZEN_WEARABLE __bt_set_visible_mode(); +#endif __bt_set_local_name(); @@ -684,24 +576,109 @@ void _bt_set_enabled(void) /* Send enabled event to API */ _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_ENABLED, DBUS_TYPE_INT32, &result, DBUS_TYPE_INVALID); + + return BLUETOOTH_ERROR_NONE; } -void _bt_set_disabled(void) +void _bt_set_disabled(int result) { - int result = BLUETOOTH_ERROR_NONE; + int power_off_status = 0; + int ret; + int ret_pm_ignore; + int pm_ignore_mode = 0; + + ret = vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &power_off_status); + BT_DBG("ret : %d, power_off_status : %d", ret, power_off_status); + + ret_pm_ignore = vconf_get_int(VCONFKEY_PM_KEY_IGNORE, &pm_ignore_mode); + + /* Update the vconf BT status in normal Deactivation case only */ + if (ret == 0 && power_off_status == VCONFKEY_SYSMAN_POWER_OFF_NONE && + ret_pm_ignore == 0 && pm_ignore_mode != VCONFKEY_PM_KEY_LOCK) { + + BT_DBG("Update vconf for BT normal Deactivation"); + + if (result == BLUETOOTH_ERROR_TIMEOUT) + 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 (vconf_set_int(VCONFKEY_BT_DEVICE, VCONFKEY_BT_DEVICE_NONE) != 0) + BT_ERR("Set vconf failed\n"); _bt_adapter_set_status(BT_DEACTIVATED); + if (_bt_adapter_get_le_status() != BT_LE_DEACTIVATED) { + /* Send disabled event */ + _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_DISABLED, + DBUS_TYPE_INT32, &result, DBUS_TYPE_INVALID); + } + + BT_INFO("Adapter disabled"); +} + +static int __bt_set_le_enabled(void) +{ + BT_DBG("+"); + int result = BLUETOOTH_ERROR_NONE; + bt_status_t status; + + __bt_set_local_name(); + +#ifdef ENABLE_TIZEN_2_4 /* Update Bluetooth Status to notify other modules */ - if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_OFF) != 0) + if (vconf_set_int(VCONFKEY_BT_LE_STATUS, VCONFKEY_BT_LE_STATUS_ON) != 0) BT_ERR("Set vconf failed\n"); +#endif + /* Send enabled event to API */ + /* + _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_ENABLED, + DBUS_TYPE_INT32, &result, DBUS_TYPE_INVALID); + */ + status = _bt_adapter_get_status(); + if (status == BT_DEACTIVATED) { + BT_INFO("BREDR is off, turn off PSCAN"); + _bt_set_connectable(FALSE); + } + if (le_timer_id > 0) { + g_source_remove(le_timer_id); + le_timer_id = 0; + } - if (vconf_set_int(VCONFKEY_BT_DEVICE, VCONFKEY_BT_DEVICE_NONE) != 0) + /* Send enabled event to API */ + _bt_send_event(BT_LE_ADAPTER_EVENT, BLUETOOTH_EVENT_LE_ENABLED, + DBUS_TYPE_INT32, &result, DBUS_TYPE_INVALID); + + BT_DBG("-"); + return BLUETOOTH_ERROR_NONE; +} + +void _bt_set_le_disabled(int result) +{ + int power_off_status; + int ret; + + ret = vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &power_off_status); + BT_DBG("ret : %d", ret); + BT_DBG("power_off_status : %d", power_off_status); + + /* Update Bluetooth Status to notify other modules */ + BT_DBG("Update vconf for BT LE normal Deactivation"); +#ifdef ENABLE_TIZEN_2_4 + 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); +#endif - /* Send disabled event */ - _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_DISABLED, + if (_bt_adapter_get_status() != BT_DEACTIVATED) { + /* Send disabled event */ + _bt_send_event(BT_LE_ADAPTER_EVENT, BLUETOOTH_EVENT_LE_DISABLED, DBUS_TYPE_INT32, &result, DBUS_TYPE_INVALID); + } } void *_bt_get_adapter_agent(void) @@ -709,17 +686,107 @@ void *_bt_get_adapter_agent(void) return adapter_agent; } -void _bt_handle_flight_mode_noti(void) +int _bt_enable_core(void) { + DBusGProxy *proxy; + + proxy = __bt_get_core_proxy(); + retv_if(!proxy, BLUETOOTH_ERROR_INTERNAL); + + if (dbus_g_proxy_call(proxy, "EnableCore", NULL, + G_TYPE_INVALID, G_TYPE_INVALID) == FALSE) { + BT_ERR("Bt core call failed"); + } + + return BLUETOOTH_ERROR_NONE; +} + +static void __bt_service_flight_ps_mode_cb(keynode_t *node, void *data) +{ + gboolean flight_mode = FALSE; + int power_saving_mode = 0; + int type; + + DBG_SECURE("key=%s", vconf_keynode_get_name(node)); + type = vconf_keynode_get_type(node); + if (type == VCONF_TYPE_BOOL) { + flight_mode = vconf_keynode_get_bool(node); + if (flight_mode != TRUE) { + BT_ERR("Ignore the event"); + return; + } + } else if (type == VCONF_TYPE_INT) { + power_saving_mode = vconf_keynode_get_int(node); + if (power_saving_mode != 2) { + BT_ERR("Ignore the event"); + return; + } + } else { + BT_ERR("Invaild vconf key type : %d", type); + return; + } + + _bt_enable_core(); +} + +void _bt_service_register_vconf_handler(void) +{ + int ret; BT_DBG("+"); - vconf_notify_key_changed(VCONFKEY_TELEPHONY_FLIGHT_MODE, - __bt_flight_mode_cb, NULL); - BT_DBG("-"); + +#ifdef TIZEN_TELEPHONY_ENABLED + ret = vconf_notify_key_changed(VCONFKEY_TELEPHONY_FLIGHT_MODE, + (vconf_callback_fn)__bt_service_flight_ps_mode_cb, NULL); + if (ret < 0) + BT_ERR("Unable to register key handler"); +#else + BT_DBG("Telephony is disabled"); +#endif + +#ifndef TIZEN_WEARABLE +#ifdef ENABLE_TIZEN_2_4 + ret = vconf_notify_key_changed(VCONFKEY_SETAPPL_PSMODE, + (vconf_callback_fn)__bt_service_flight_ps_mode_cb, NULL); + if (ret < 0) + BT_ERR("Unable to register key handler"); +#endif +#endif +} + +void _bt_service_unregister_vconf_handler(void) +{ + BT_DBG("+"); + +#ifdef TIZEN_TELEPHONY_ENABLED + vconf_ignore_key_changed(VCONFKEY_TELEPHONY_FLIGHT_MODE, + (vconf_callback_fn)__bt_service_flight_ps_mode_cb); +#endif + +#ifndef TIZEN_WEARABLE +#ifdef ENABLE_TIZEN_2_4 + vconf_ignore_key_changed(VCONFKEY_SETAPPL_PSMODE, + (vconf_callback_fn)__bt_service_flight_ps_mode_cb); +#endif +#endif } void _bt_handle_adapter_added(void) { - BT_DBG(""); + BT_DBG("+"); + 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); adapter_agent = _bt_create_agent(BT_ADAPTER_AGENT_PATH, TRUE); if (!adapter_agent) { @@ -727,81 +794,173 @@ void _bt_handle_adapter_added(void) return; } -#ifdef __TIZEN_MOBILE__ - if (!aul_app_is_running("com.samsung.bluetooth")) - __launch_bt_service(0, 0); - if (_bt_register_media_player() != BLUETOOTH_ERROR_NONE) BT_ERR("Fail to register media player"); -#endif if (_bt_register_obex_server() != BLUETOOTH_ERROR_NONE) BT_ERR("Fail to init obex server"); -/* + +#ifndef TIZEN_WEARABLE if (_bt_network_activate() != BLUETOOTH_ERROR_NONE) BT_ERR("Fail to activate network"); -*/ +#endif /* add the vconf noti handler */ - vconf_notify_key_changed(VCONFKEY_SETAPPL_DEVICE_NAME_STR, + ret = vconf_notify_key_changed(VCONFKEY_SETAPPL_DEVICE_NAME_STR, __bt_phone_name_changed_cb, NULL); + if (ret < 0) + BT_ERR("Unable to register key handler"); + + if (le_status == BT_LE_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); + } +// journal_bt_on(); - vconf_notify_key_changed(VCONFKEY_TELEPHONY_FLIGHT_MODE, - __bt_flight_mode_cb, NULL); + _bt_service_register_vconf_handler(); } void _bt_handle_adapter_removed(void) { - BT_DBG(""); + int ret; + + _bt_adapter_set_status(BT_DEACTIVATED); +// journal_bt_off(); + + __bt_visibility_alarm_remove(); + + if (visible_timer.alarm_init) { + alarmmgr_fini(); + visible_timer.alarm_init = FALSE; + } - vconf_ignore_key_changed(VCONFKEY_SETAPPL_DEVICE_NAME_STR, + ret = vconf_ignore_key_changed(VCONFKEY_SETAPPL_DEVICE_NAME_STR, (vconf_callback_fn)__bt_phone_name_changed_cb); + if (0 != ret) { + ERR("vconf_ignore_key_changed failed\n"); + } _bt_destroy_agent(adapter_agent); adapter_agent = NULL; + _bt_reliable_terminate_service(NULL); +} + +static gboolean __bt_enable_timeout_cb(gpointer user_data) +{ + DBusGProxy *proxy; + + timer_id = 0; + + retv_if(_bt_adapter_get_status() == BT_ACTIVATED, FALSE); + + BT_ERR("EnableAdapter is failed"); + + proxy = __bt_get_core_proxy(); + if (!proxy) + return FALSE; + + /* Clean up the process */ + if (dbus_g_proxy_call(proxy, "DisableAdapter", NULL, + G_TYPE_INVALID, G_TYPE_INVALID) == FALSE) { + BT_ERR("Bt core call failed"); + } + + _bt_set_disabled(BLUETOOTH_ERROR_TIMEOUT); + + /* Display notification */ + notification_status_message_post(BT_STR_NOT_SUPPORT); + _bt_terminate_service(NULL); + + return FALSE; } -DBusGProxy *_bt_init_core_proxy(void) +static gboolean __bt_enable_le_timeout_cb(gpointer user_data) { DBusGProxy *proxy; - DBusGConnection *conn; - conn = _bt_get_system_gconn(); - if (!conn) - return NULL; + le_timer_id = 0; - proxy = dbus_g_proxy_new_for_name(conn, BT_CORE_NAME, - BT_CORE_PATH, BT_CORE_INTERFACE); + retv_if(_bt_adapter_get_le_status() == BT_LE_ACTIVATED, FALSE); + + BT_ERR("EnableAdapterLE is failed"); + + proxy = __bt_get_core_proxy(); if (!proxy) - return NULL; + return FALSE; - core_proxy = proxy; + /* Clean up the process */ + if (dbus_g_proxy_call(proxy, "DisableAdapterLe", NULL, + G_TYPE_INVALID, G_TYPE_INVALID) == FALSE) { + BT_ERR("Bt core call failed"); + } - return proxy; + _bt_adapter_set_le_status(BT_LE_DEACTIVATED); + + _bt_set_le_disabled(BLUETOOTH_ERROR_TIMEOUT); + + /* Display notification */ + notification_status_message_post(BT_STR_NOT_SUPPORT); + + if (_bt_adapter_get_status() == BT_DEACTIVATED) + _bt_terminate_service(NULL); + + return FALSE; } -static DBusGProxy *__bt_get_core_proxy(void) +void _bt_adapter_start_le_enable_timer(void) +{ + if (le_timer_id > 0) { + g_source_remove(le_timer_id); + le_timer_id = 0; + } + + le_timer_id = g_timeout_add(BT_ENABLE_TIMEOUT, + __bt_enable_le_timeout_cb, NULL); + + return; +} + +void _bt_adapter_start_enable_timer(void) { - return (core_proxy) ? core_proxy : _bt_init_core_proxy(); + if (timer_id > 0) { + g_source_remove(timer_id); + timer_id = 0; + } + + timer_id = g_timeout_add(BT_ENABLE_TIMEOUT, + __bt_enable_timeout_cb, NULL); + + return; } int _bt_enable_adapter(void) { DBusGProxy *proxy; GError *err = NULL; - + int ret; + bt_status_t status = _bt_adapter_get_status(); + bt_le_status_t le_status = _bt_adapter_get_le_status(); BT_DBG(""); - if (_bt_adapter_get_status() == BT_ACTIVATING) { - BT_DBG("Enabling in progress"); - return BLUETOOTH_ERROR_IN_PROGRESS; + 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 (_bt_adapter_get_status() == BT_ACTIVATED) { - BT_DBG("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; } _bt_adapter_set_status(BT_ACTIVATING); @@ -810,6 +969,16 @@ int _bt_enable_adapter(void) if (!proxy) return BLUETOOTH_ERROR_INTERNAL; + 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) { + _bt_adapter_set_status(BT_ACTIVATED); + } else { + return BLUETOOTH_ERROR_INTERNAL; + } + } + if (dbus_g_proxy_call_with_timeout(proxy, "EnableAdapter", BT_ENABLE_TIMEOUT, &err, G_TYPE_INVALID, @@ -836,38 +1005,181 @@ int _bt_enable_adapter(void) return BLUETOOTH_ERROR_INTERNAL; } + if (le_status == BT_LE_ACTIVATED) { + __bt_set_enabled(); + } else { + _bt_adapter_start_enable_timer(); + } + return BLUETOOTH_ERROR_NONE; } -int _bt_disable_adapter(void) +static gboolean __bt_disconnect_all(void) { - DBusGProxy *proxy; + int i; + DBusGConnection *conn; + DBusGProxy *dev_proxy; + gboolean ret = FALSE; + + GArray *device_list; + bluetooth_device_info_t info; + guint size; + char *device_path = NULL; + char address[BT_ADDRESS_STRING_SIZE] = { 0 }; + + + BT_DBG(""); + + conn = _bt_get_system_gconn(); + + device_list = g_array_new(FALSE, FALSE, sizeof(gchar)); + + if (_bt_get_bonded_devices(&device_list) + != BLUETOOTH_ERROR_NONE) { + g_array_free(device_list, TRUE); + return FALSE; + } + + size = (device_list->len) / sizeof(bluetooth_device_info_t); + + for (i = 0; i < size; i++) { + + info = g_array_index(device_list, + bluetooth_device_info_t, i); + + if (info.connected == TRUE) { + BT_DBG("Found Connected device"); + _bt_convert_addr_type_to_string(address, info.device_address.addr); + device_path = _bt_get_device_object_path(address); + if (device_path == NULL) + continue; + + BT_DBG("Disconnecting : %s", device_path); + + dev_proxy = dbus_g_proxy_new_for_name(conn, BT_BLUEZ_NAME, + device_path, BT_DEVICE_INTERFACE); + if (dev_proxy == NULL) + continue; + + if(!dbus_g_proxy_call(dev_proxy, "Disconnect", + NULL, G_TYPE_INVALID, G_TYPE_INVALID)) { + BT_ERR("Disconnect fail error."); + g_object_unref(dev_proxy); + return FALSE; + } + } + } + ret = TRUE; + g_array_free(device_list, TRUE); + + return ret; +} +static gboolean __bt_set_disabled_timeout_cb(gpointer user_data) +{ BT_DBG(""); + _bt_set_disabled(BLUETOOTH_ERROR_NONE); + + return FALSE; +} + +int __bt_disable_cb(void) +{ + FN_START; + DBusGProxy *proxy; + bt_le_status_t le_status; + int ret; + + _bt_adapter_set_status(BT_DEACTIVATING); + le_status = _bt_adapter_get_le_status(); + BT_DBG("le_status : %d", le_status); + if (le_status == BT_LE_ACTIVATED) { + BT_INFO("LE is enabled. Just turn off PSCAN"); + + if (_bt_is_discovering()) + _bt_cancel_discovery(); + + if (_bt_is_connectable() == FALSE) { + g_timeout_add(100, (GSourceFunc)__bt_set_disabled_timeout_cb, NULL); + } else { + ret = _bt_set_connectable(FALSE); + if (ret != BLUETOOTH_ERROR_NONE) { + BT_ERR("_bt_set_connectable fail!"); + _bt_adapter_set_status(BT_ACTIVATED); + return BLUETOOTH_ERROR_INTERNAL; + } + } + } + + proxy = __bt_get_core_proxy(); + retv_if(!proxy, BLUETOOTH_ERROR_INTERNAL); + + if (dbus_g_proxy_call(proxy, "DisableAdapter", NULL, + G_TYPE_INVALID, G_TYPE_INVALID) == FALSE) { + BT_ERR("Bt core call failed"); + _bt_adapter_set_status(BT_ACTIVATED); + return BLUETOOTH_ERROR_INTERNAL; + } + + return BLUETOOTH_ERROR_NONE; +} + +int _bt_disable_adapter(void) +{ + BT_DBG("+"); + int ret; if (_bt_adapter_get_status() == BT_DEACTIVATING) { - BT_DBG("Disabling in progress"); - return BLUETOOTH_ERROR_IN_PROGRESS; + BT_DBG("Disabling in progress"); + return BLUETOOTH_ERROR_IN_PROGRESS; } if (_bt_adapter_get_status() == BT_DEACTIVATED) { - BT_DBG("Already disabled"); - return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED; + BT_DBG("Already disabled"); + return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED; + } + + if (timer_id > 0) { + g_source_remove(timer_id); + timer_id = 0; + } + + __bt_disconnect_all(); + ret = __bt_disable_cb(); + + BT_DBG("-"); + return ret; +} + +int _bt_recover_adapter(void) +{ + BT_DBG("+"); + DBusGProxy *proxy; + + if (_bt_adapter_get_status() == BT_DEACTIVATING) { + BT_DBG("Disabling in progress"); + return BLUETOOTH_ERROR_IN_PROGRESS; + } + + if (_bt_adapter_get_status() == BT_DEACTIVATED) { + BT_DBG("Already disabled"); + return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED; } _bt_adapter_set_status(BT_DEACTIVATING); proxy = __bt_get_core_proxy(); - if (!proxy) - return BLUETOOTH_ERROR_INTERNAL; + retv_if(!proxy, BLUETOOTH_ERROR_INTERNAL); - if (dbus_g_proxy_call(proxy, "DisableAdapter", NULL, + if (dbus_g_proxy_call(proxy, "RecoverAdapter", NULL, G_TYPE_INVALID, G_TYPE_INVALID) == FALSE) { BT_ERR("Bt core call failed"); - _bt_adapter_set_status(BT_ACTIVATED); return BLUETOOTH_ERROR_INTERNAL; } + __bt_disconnect_all(); + + BT_ERR("-"); return BLUETOOTH_ERROR_NONE; } @@ -895,20 +1207,130 @@ int _bt_reset_adapter(void) return BLUETOOTH_ERROR_NONE; } -int _bt_check_adapter(int *status) -{ - BT_CHECK_PARAMETER(status, return); +int _bt_check_adapter(int *status) +{ + + char *adapter_path = NULL; + + BT_CHECK_PARAMETER(status, return); + + *status = BT_ADAPTER_DISABLED; + + adapter_path = _bt_get_adapter_path(); + + + if (adapter_path != NULL) + *status = BT_ADAPTER_ENABLED; + + g_free(adapter_path); + return BLUETOOTH_ERROR_NONE; +} + +int _bt_enable_adapter_le(void) +{ + BT_DBG("+"); + DBusGProxy *proxy; + GError *err = NULL; + bt_status_t status = _bt_adapter_get_status(); + bt_le_status_t le_status = _bt_adapter_get_le_status(); + + if (le_status == BT_LE_ACTIVATING) { + BT_ERR("Enabling in progress"); + return BLUETOOTH_ERROR_IN_PROGRESS; + } + + if (le_status == BT_LE_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; + } + + _bt_adapter_set_le_status(BT_LE_ACTIVATING); + + proxy = __bt_get_core_proxy(); + retv_if(!proxy, BLUETOOTH_ERROR_INTERNAL); + + if (dbus_g_proxy_call_with_timeout(proxy, "EnableAdapterLe", + BT_ENABLE_TIMEOUT, &err, + G_TYPE_INVALID, + G_TYPE_INVALID) == FALSE) { + + _bt_adapter_set_le_status(BT_DEACTIVATED); + + if (err != NULL) { + BT_ERR("Bt core call failed: [%s]", err->message); + g_error_free(err); + } + + /* Clean up the process */ + if (dbus_g_proxy_call(proxy, "DisableAdapterLe", NULL, + G_TYPE_INVALID, G_TYPE_INVALID) == FALSE) { + BT_ERR("Bt core call failed"); + } + + /* Display notification */ + notification_status_message_post(BT_STR_NOT_SUPPORT); + + /* Terminate myself */ + if (_bt_adapter_get_status() == BT_DEACTIVATED) + g_idle_add((GSourceFunc)_bt_terminate_service, NULL); + return BLUETOOTH_ERROR_INTERNAL; + } + + _bt_adapter_start_le_enable_timer(); + + if (status == BT_ACTIVATED) { + _bt_adapter_set_le_status(BT_LE_ACTIVATED); + __bt_set_le_enabled(); + } + BT_DBG("le status : %d", _bt_adapter_get_le_status()); + BT_DBG("-"); + return BLUETOOTH_ERROR_NONE; +} + +int _bt_disable_adapter_le(void) +{ + BT_DBG("+"); + DBusGProxy *proxy; + bt_le_status_t bt_le_state; + + bt_le_state = _bt_adapter_get_le_status(); + if (bt_le_state == BT_LE_DEACTIVATING) { + BT_DBG("Disabling in progress"); + return BLUETOOTH_ERROR_IN_PROGRESS; + } + + if (bt_le_state == BT_LE_DEACTIVATED) { + BT_DBG("Already disabled"); + return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED; + } - *status = 0; /* 0: disabled */ + _bt_adapter_set_le_status(BT_LE_DEACTIVATING); + + proxy = __bt_get_core_proxy(); + if (!proxy) + return BLUETOOTH_ERROR_INTERNAL; - if (_bt_get_adapter_power()) - *status = 1; /* 1: enabled */ + if (dbus_g_proxy_call(proxy, "DisableAdapterLe", NULL, + G_TYPE_INVALID, G_TYPE_INVALID) == FALSE) { + BT_ERR("Bt core call failed"); + _bt_adapter_set_le_status(BT_LE_ACTIVATED); + return BLUETOOTH_ERROR_INTERNAL; + } + _bt_set_le_disabled(BLUETOOTH_ERROR_NONE); + BT_DBG("le status : %d", _bt_adapter_get_le_status()); + BT_DBG("-"); return BLUETOOTH_ERROR_NONE; } int _bt_get_local_address(bluetooth_device_address_t *local_address) { + DBusGProxy *proxy; GError *err = NULL; char *address; @@ -943,15 +1365,65 @@ int _bt_get_local_address(bluetooth_device_address_t *local_address) return BLUETOOTH_ERROR_NONE; } -int _bt_get_local_name(bluetooth_device_name_t *local_name) +int _bt_get_local_version(bluetooth_version_t *local_version) { DBusGProxy *proxy; + GHashTable *hash = NULL; + char *ver = NULL; + char *ptr = NULL; + int ret = BLUETOOTH_ERROR_NONE; + + BT_CHECK_PARAMETER(local_version, return); + GError *err = NULL; - GValue name_v = { 0 }; + GValue version_v = { 0 }; + + proxy = _bt_get_adapter_properties_proxy(); + retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL); + + if (!dbus_g_proxy_call(proxy, "Get", &err, + G_TYPE_STRING, BT_ADAPTER_INTERFACE, + G_TYPE_STRING, "Version", + G_TYPE_INVALID, + G_TYPE_VALUE, &version_v, + G_TYPE_INVALID)) { + if (err != NULL) { + BT_ERR("Getting property failed: [%s]\n", err->message); + g_error_free(err); + } + return BLUETOOTH_ERROR_INTERNAL; + } + + ver = (char *)g_value_get_string(&version_v); + + + if (ver && (strlen(ver) > 0)) { + /* Check the utf8 valitation & Fill the NULL in the invalid location*/ + if (!g_utf8_validate(ver, -1, (const char **)&ptr)) + *ptr = '\0'; + + g_strlcpy(local_version->version, ver, + BLUETOOTH_VERSION_LENGTH_MAX + 1); + + } else { + ret = BLUETOOTH_ERROR_INTERNAL; + } + + g_hash_table_destroy(hash); + return ret; +} + +int _bt_get_local_name(bluetooth_device_name_t *local_name) +{ + DBusGProxy *proxy; + GHashTable *hash = NULL; char *name = NULL; char *ptr = NULL; int ret = BLUETOOTH_ERROR_NONE; + GError *err = NULL; + GValue name_v = { 0 }; + BT_CHECK_PARAMETER(local_name, return); proxy = _bt_get_adapter_properties_proxy(); @@ -983,6 +1455,7 @@ int _bt_get_local_name(bluetooth_device_name_t *local_name) ret = BLUETOOTH_ERROR_INTERNAL; } + g_hash_table_destroy(hash); return ret; } @@ -996,6 +1469,7 @@ int _bt_set_local_name(char *local_name) BT_CHECK_PARAMETER(local_name, return); proxy = _bt_get_adapter_properties_proxy(); + retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL); if (!g_utf8_validate(local_name, -1, (const char **)&ptr)) @@ -1026,25 +1500,31 @@ int _bt_is_service_used(char *service_uuid, gboolean *used) char **uuids; int i; DBusGProxy *proxy; - GHashTable *hash = NULL; - GValue *value; + GError *err = NULL; + GValue uuids_v = { 0 }; int ret = BLUETOOTH_ERROR_NONE; + BT_DBG("+"); BT_CHECK_PARAMETER(service_uuid, return); BT_CHECK_PARAMETER(used, return); - proxy = _bt_get_adapter_proxy(); + proxy = _bt_get_adapter_properties_proxy(); retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL); - dbus_g_proxy_call(proxy, "GetProperties", NULL, - G_TYPE_INVALID, - dbus_g_type_get_map("GHashTable", G_TYPE_STRING, - G_TYPE_VALUE), &hash, G_TYPE_INVALID); - - retv_if(hash == NULL, BLUETOOTH_ERROR_INTERNAL); + if (!dbus_g_proxy_call(proxy, "Get", &err, + G_TYPE_STRING, BT_ADAPTER_INTERFACE, + G_TYPE_STRING, "UUIDs", + G_TYPE_INVALID, + G_TYPE_VALUE, &uuids_v, + G_TYPE_INVALID)) { + if (err != NULL) { + BT_ERR("Getting property failed: [%s]\n", err->message); + g_error_free(err); + } + return BLUETOOTH_ERROR_INTERNAL; + } - value = g_hash_table_lookup(hash, "UUIDs"); - uuids = g_value_get_boxed(value); + uuids = g_value_get_boxed(&uuids_v); if (uuids == NULL) { /* Normal case */ @@ -1061,10 +1541,11 @@ int _bt_is_service_used(char *service_uuid, gboolean *used) *used = FALSE; done: - g_hash_table_destroy(hash); + BT_DBG("Service Used? %d", *used); return ret; } + static gboolean __bt_get_discoverable_property(void) { DBusGProxy *proxy; @@ -1072,7 +1553,7 @@ static gboolean __bt_get_discoverable_property(void) GError *err = NULL; proxy = _bt_get_adapter_properties_proxy(); - retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL); + retv_if(proxy == NULL, FALSE); if (!dbus_g_proxy_call(proxy, "Get", &err, G_TYPE_STRING, BT_ADAPTER_INTERFACE, @@ -1084,7 +1565,7 @@ static gboolean __bt_get_discoverable_property(void) BT_ERR("Getting property failed: [%s]\n", err->message); g_error_free(err); } - return BLUETOOTH_ERROR_INTERNAL; + return FALSE; } return g_value_get_boolean(&discoverable_v); @@ -1111,6 +1592,7 @@ int _bt_get_discoverable_mode(int *mode) return BLUETOOTH_ERROR_NONE; } + int _bt_set_discoverable_mode(int discoverable_mode, int timeout) { int ret = BLUETOOTH_ERROR_NONE; @@ -1123,6 +1605,7 @@ int _bt_set_discoverable_mode(int discoverable_mode, int timeout) DBusGProxy *proxy; proxy = _bt_get_adapter_properties_proxy(); + retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL); g_value_init(&connectable, G_TYPE_BOOLEAN); @@ -1148,18 +1631,21 @@ int _bt_set_discoverable_mode(int discoverable_mode, int timeout) return BLUETOOTH_ERROR_INVALID_PARAM; } + BT_INFO("Req. discoverable_mode : %d, timeout : %d", + discoverable_mode, timeout); + g_value_set_boolean(&connectable, pg_scan); g_value_set_boolean(&discoverable, inq_scan); g_value_set_uint(&val_timeout, timeout); dbus_g_proxy_call(proxy, "Set", &error, G_TYPE_STRING, BT_ADAPTER_INTERFACE, - G_TYPE_STRING, "Powered", + G_TYPE_STRING, "Connectable", G_TYPE_VALUE, &connectable, G_TYPE_INVALID, G_TYPE_INVALID); if (error != NULL) { - BT_ERR("Powered set err:[%s]", error->message); + BT_ERR("Connectable set err:[%s]", error->message); g_error_free(error); ret = BLUETOOTH_ERROR_INTERNAL; goto done; @@ -1171,6 +1657,7 @@ int _bt_set_discoverable_mode(int discoverable_mode, int timeout) G_TYPE_VALUE, &discoverable, G_TYPE_INVALID, G_TYPE_INVALID); + if (error != NULL) { BT_ERR("Discoverable set err:[%s]", error->message); g_error_free(error); @@ -1194,7 +1681,7 @@ int _bt_set_discoverable_mode(int discoverable_mode, int timeout) if (discoverable_mode == BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE) timeout = -1; - __bt_set_visible_time(timeout); + ret = __bt_set_visible_time(timeout); done: g_value_unset(&val_timeout); @@ -1207,22 +1694,65 @@ done: int _bt_start_discovery(void) { DBusGProxy *proxy; + GError *err = NULL; if (_bt_is_discovering() == TRUE) { BT_ERR("BT is already in discovering"); return BLUETOOTH_ERROR_IN_PROGRESS; + } else if (_bt_is_device_creating() == TRUE) { + BT_ERR("Bonding device is going on"); + return BLUETOOTH_ERROR_DEVICE_BUSY; } proxy = _bt_get_adapter_proxy(); retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL); - if (!dbus_g_proxy_call(proxy, "StartDiscovery", NULL, + if (!dbus_g_proxy_call(proxy, "StartDiscovery", &err, G_TYPE_INVALID, G_TYPE_INVALID)) { + if (err != NULL) { + BT_ERR("StartDiscovery failed: [%s]\n", err->message); + g_error_free(err); + } BT_ERR("Discover start failed"); return BLUETOOTH_ERROR_INTERNAL; } - _bt_stop_discovery_timeout(); + is_discovering = TRUE; + cancel_by_user = FALSE; + /* discovery status will be change in event */ + + return BLUETOOTH_ERROR_NONE; +} + +int _bt_start_custom_discovery(bt_discovery_role_type_t role) +{ + DBusGProxy *proxy; + + const gchar *disc_type; + + if (_bt_is_discovering() == TRUE) { + BT_ERR("BT is already in discovering"); + return BLUETOOTH_ERROR_IN_PROGRESS; + } + + proxy = _bt_get_adapter_proxy(); + retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL); + + if (role == DISCOVERY_ROLE_BREDR) + disc_type = "BREDR"; + else if (role == DISCOVERY_ROLE_LE) + disc_type = "LE"; + else if (role == DISCOVERY_ROLE_LE_BREDR) + disc_type = "LE_BREDR"; + else + return BLUETOOTH_ERROR_INVALID_PARAM; + + if (!dbus_g_proxy_call(proxy, "StartCustomDiscovery", NULL, + G_TYPE_STRING, disc_type, + G_TYPE_INVALID, G_TYPE_INVALID)) { + BT_ERR("StartCustomDiscovery failed"); + return BLUETOOTH_ERROR_INTERNAL; + } is_discovering = TRUE; cancel_by_user = FALSE; @@ -1234,6 +1764,7 @@ int _bt_start_discovery(void) int _bt_cancel_discovery(void) { DBusGProxy *proxy; + GError *err = NULL; if (_bt_is_discovering() == FALSE) { BT_ERR("BT is not in discovering"); @@ -1243,9 +1774,12 @@ int _bt_cancel_discovery(void) proxy = _bt_get_adapter_proxy(); retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL); - if (!dbus_g_proxy_call(proxy, "StopDiscovery", NULL, + if (!dbus_g_proxy_call(proxy, "StopDiscovery", &err, G_TYPE_INVALID, G_TYPE_INVALID)) { - BT_ERR("Discover stop failed"); + if (err != NULL) { + BT_ERR("StopDiscovery failed: [%s]\n", err->message); + g_error_free(err); + } return BLUETOOTH_ERROR_INTERNAL; } @@ -1255,23 +1789,143 @@ int _bt_cancel_discovery(void) return BLUETOOTH_ERROR_NONE; } +int _bt_start_le_discovery(void) +{ + DBusGProxy *proxy; + + if (_bt_is_le_discovering() == TRUE) { + BT_ERR("BT is already in LE discovering"); + return BLUETOOTH_ERROR_IN_PROGRESS; + } + + proxy = _bt_get_adapter_proxy(); + retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL); + + if (!dbus_g_proxy_call(proxy, "StartLEDiscovery", NULL, + G_TYPE_INVALID, G_TYPE_INVALID)) { + BT_ERR("LE Discover start failed"); + return BLUETOOTH_ERROR_INTERNAL; + } + + is_le_discovering = TRUE; + + return BLUETOOTH_ERROR_NONE; +} + +int _bt_stop_le_discovery(void) +{ + DBusGProxy *proxy; + + if (_bt_is_le_discovering() == FALSE) { + BT_ERR("BT is not in LE discovering"); + return BLUETOOTH_ERROR_NOT_IN_OPERATION; + } + + proxy = _bt_get_adapter_proxy(); + retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL); + + if (!dbus_g_proxy_call(proxy, "StopLEDiscovery", NULL, + G_TYPE_INVALID, G_TYPE_INVALID)) { + BT_ERR("LE Discover stop failed"); + return BLUETOOTH_ERROR_INTERNAL; + } + + return BLUETOOTH_ERROR_NONE; +} + gboolean _bt_is_discovering(void) { return is_discovering; } -gboolean _bt_get_discovering_property(void) +gboolean _bt_is_le_discovering(void) +{ + return is_le_discovering; +} + +gboolean _bt_is_connectable(void) +{ + DBusGProxy *proxy; + GValue connectable_v = { 0 }; + GError *err = NULL; + gboolean is_connectable = FALSE; + + proxy = _bt_get_adapter_properties_proxy(); + retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL); + + if (!dbus_g_proxy_call(proxy, "Get", &err, + G_TYPE_STRING, BT_ADAPTER_INTERFACE, + G_TYPE_STRING, "Connectable", + G_TYPE_INVALID, + G_TYPE_VALUE, &connectable_v, + G_TYPE_INVALID)) { + if (err != NULL) { + BT_ERR("Getting property failed: [%s]\n", err->message); + g_error_free(err); + } + return BLUETOOTH_ERROR_INTERNAL; + } + + is_connectable = g_value_get_boolean(&connectable_v); + BT_INFO("Get connectable [%d]", is_connectable); + + return is_connectable; +} + +int _bt_set_connectable(gboolean is_connectable) +{ + DBusGProxy *proxy; + GValue connectable = { 0 }; + GError *error = NULL; + + if (__bt_is_factory_test_mode()) { + BT_ERR("Unable to set connectable in factory binary !!"); + return BLUETOOTH_ERROR_NOT_SUPPORT; + } + + proxy = _bt_get_adapter_properties_proxy(); + + retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL); + + g_value_init(&connectable, G_TYPE_BOOLEAN); + g_value_set_boolean(&connectable, is_connectable); + + dbus_g_proxy_call(proxy, "Set", &error, + G_TYPE_STRING, BT_ADAPTER_INTERFACE, + G_TYPE_STRING, "Connectable", + G_TYPE_VALUE, &connectable, + G_TYPE_INVALID, G_TYPE_INVALID); + + g_value_unset(&connectable); + if (error != NULL) { + BT_ERR("Connectable set err:[%s]", error->message); + g_error_free(error); + return BLUETOOTH_ERROR_INTERNAL; + } + + BT_INFO("Set connectable [%d]", is_connectable); + return BLUETOOTH_ERROR_NONE; +} + +gboolean _bt_get_discovering_property(bt_discovery_role_type_t discovery_type) { + DBusGProxy *proxy; GValue discovering_v = { 0 }; GError *err = NULL; + char *discovering_type = NULL; proxy = _bt_get_adapter_properties_proxy(); retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL); + if (discovery_type == DISCOVERY_ROLE_BREDR) + discovering_type = "Discovering"; + else if (discovery_type == DISCOVERY_ROLE_LE) + discovering_type = "LEDiscovering"; + if (!dbus_g_proxy_call(proxy, "Get", &err, G_TYPE_STRING, BT_ADAPTER_INTERFACE, - G_TYPE_STRING, "Discovering", + G_TYPE_STRING, discovering_type, G_TYPE_INVALID, G_TYPE_VALUE, &discovering_v, G_TYPE_INVALID)) { @@ -1283,6 +1937,7 @@ gboolean _bt_get_discovering_property(void) } return g_value_get_boolean(&discovering_v); + } unsigned int _bt_get_discoverable_timeout_property(void) @@ -1415,6 +2070,22 @@ static bluetooth_device_info_t *__bt_parse_device_info(DBusMessageIter *item_ite } dev_info->service_index = i; + } else if (strcasecmp(key, "ManufacturerDataLen") == 0) { + dbus_message_iter_get_basic(&iter_dict_val, + &dev_info->manufacturer_data.data_len); + } else if (strcasecmp(key, "ManufacturerData") == 0) { + DBusMessageIter manufacturer_iter; + int i = 0; + char byte = 0; + + dbus_message_iter_recurse(&iter_dict_val, &manufacturer_iter); + + while (dbus_message_iter_get_arg_type(&manufacturer_iter) == DBUS_TYPE_BYTE) { + dbus_message_iter_get_basic(&manufacturer_iter, &byte); + dev_info->manufacturer_data.data[i] = byte; + i++; + dbus_message_iter_next(&manufacturer_iter); + } } dbus_message_iter_next(&value_iter); @@ -1466,12 +2137,13 @@ static void __bt_extract_device_info(DBusMessageIter *msg_iter, dev_info = __bt_parse_device_info(&interface_iter); if (dev_info) { - if (dev_info->paired == TRUE) { - g_array_append_vals(*dev_list, dev_info, - sizeof(bluetooth_device_info_t)); - } else { - g_free(dev_info); - } + if (dev_info->paired == FALSE) + goto not_paired; + + g_array_append_vals(*dev_list, dev_info, + sizeof(bluetooth_device_info_t)); + + g_free(dev_info); } return; @@ -1481,10 +2153,15 @@ static void __bt_extract_device_info(DBusMessageIter *msg_iter, } BT_DBG("There is no device interface"); + +not_paired: + BT_DBG("Not paired"); + g_free(dev_info); } int _bt_get_bonded_devices(GArray **dev_list) { + BT_DBG("+"); DBusMessage *msg; DBusMessage *reply; DBusMessageIter reply_iter; @@ -1519,8 +2196,9 @@ int _bt_get_bonded_devices(GArray **dev_list) } if (dbus_message_iter_init(reply, &reply_iter) == FALSE) { - BT_ERR("Fail to iterate the reply"); - return BLUETOOTH_ERROR_INTERNAL; + BT_ERR("Fail to iterate the reply"); + dbus_message_unref(reply); + return BLUETOOTH_ERROR_INTERNAL; } dbus_message_iter_recurse(&reply_iter, &value_iter); @@ -1536,7 +2214,8 @@ int _bt_get_bonded_devices(GArray **dev_list) dbus_message_iter_next(&value_iter); } - + dbus_message_unref(reply); + BT_DBG("-"); return BLUETOOTH_ERROR_NONE; } @@ -1546,6 +2225,7 @@ int _bt_get_bonded_device_info(bluetooth_device_address_t *device_address, char *object_path = NULL; DBusGProxy *adapter_proxy; char address[BT_ADDRESS_STRING_SIZE] = { 0 }; + int ret = BLUETOOTH_ERROR_NONE; BT_CHECK_PARAMETER(device_address, return); BT_CHECK_PARAMETER(dev_info, return); @@ -1557,16 +2237,12 @@ int _bt_get_bonded_device_info(bluetooth_device_address_t *device_address, object_path = _bt_get_device_object_path(address); - retv_if(object_path == NULL, BLUETOOTH_ERROR_NOT_FOUND); + retv_if(object_path == NULL, BLUETOOTH_ERROR_NOT_PAIRED); - if (__bt_get_bonded_device_info(object_path, - dev_info) != BLUETOOTH_ERROR_NONE) { - BT_ERR("Can't get the paired device path \n"); - g_free(object_path); - return BLUETOOTH_ERROR_INTERNAL; - } + ret = __bt_get_bonded_device_info(object_path, dev_info); g_free(object_path); - return BLUETOOTH_ERROR_NONE; + + return ret; } int _bt_get_timeout_value(int *timeout) @@ -1585,3 +2261,85 @@ int _bt_get_timeout_value(int *timeout) return BLUETOOTH_ERROR_NONE; } +int _bt_set_le_privacy(gboolean set_privacy) +{ + DBusGProxy *proxy; + GError *error = NULL; + int ret = BLUETOOTH_ERROR_NONE; + + if (__bt_is_factory_test_mode()) { + BT_ERR("Unable to set le privacy 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); + + dbus_g_proxy_call(proxy, "SetLePrivacy", &error, + G_TYPE_BOOLEAN, set_privacy, + G_TYPE_INVALID, G_TYPE_INVALID); + + if (error) { + BT_ERR("SetLePrivacy Failed :[%s]", error->message); + if (g_strrstr(error->message, BT_SERVICE_ERR_MSG_NOT_SUPPORTED)) + ret = BLUETOOTH_ERROR_NOT_SUPPORT; + else + ret = BLUETOOTH_ERROR_INTERNAL; + g_error_free(error); + return ret; + } + + BT_INFO("SetLePrivacy as %d", set_privacy); + + return BLUETOOTH_ERROR_NONE; +} + +int _bt_set_manufacturer_data(bluetooth_manufacturer_data_t *m_data) +{ + DBusGProxy *proxy; + GError *error = NULL; + GArray *arr; + int i; + + BT_CHECK_PARAMETER(m_data, return); + + 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); + + arr = g_array_new(TRUE, TRUE, sizeof(guint8)); + + for (i = 0; i < (m_data->data_len) + 2; i++) + g_array_append_vals(arr, &(m_data->data[i]), sizeof(guint8)); + + dbus_g_proxy_call(proxy, "SetManufacturerData", &error, + DBUS_TYPE_G_UCHAR_ARRAY, arr, + G_TYPE_INVALID, G_TYPE_INVALID); + + g_array_free(arr, TRUE); + + if (error) { + BT_ERR("SetManufacturerData Fail: %s", error->message); + g_error_free(error); + return BLUETOOTH_ERROR_INTERNAL; + } + + _bt_send_event(BT_ADAPTER_EVENT, + BLUETOOTH_EVENT_MANUFACTURER_DATA_CHANGED, + DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, + &m_data, m_data->data_len, + DBUS_TYPE_INVALID); + + BT_INFO("Set manufacturer data"); + + return BLUETOOTH_ERROR_NONE; +}