GList *g_alarm_list;
} bt_service_alarm_mgr_t;
+#define BT_RECOVERY_MAX_COUNT 3
+
static bt_service_alarm_mgr_t alarm_mgr = {0, };
static gboolean is_discovering;
+static gboolean discovery_req;
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 GDBusProxy *core_proxy = NULL;
static guint timer_id = 0;
static guint le_timer_id = 0;
-static gboolean is_recovery_mode;
+static int recovery_cnt = BT_RECOVERY_MAX_COUNT;
+static guint recovery_timer = 0;
static uint status_reg_id;
#define BT_DISABLE_TIME 500 /* 500 ms */
+#define BT_RECOVERY_TIME_W 2000 /*2 sec*/
+#define BT_RECOVERY_TIME 5000 /*5 sec*/
+
static int alarm_cb(alarm_id_t alarm_id, void* user_param);
static void alarm_data_free(void *data);
GDBusProxy *device_proxy;
gchar *address = NULL;
gchar *name = NULL;
+ gchar *alias = NULL;
unsigned int cod = 0;
gint rssi = 0;
gboolean trust = FALSE;
} else if (!g_strcmp0(key, "Address")) {
g_variant_get(value, "s", &address);
} else if (!g_strcmp0(key, "Alias")) {
- g_variant_get(value, "s", &name);
+ g_variant_get(value, "s", &alias);
} else if (!g_strcmp0(key, "Name")) {
- if (!name)
- g_variant_get(value, "s", &name);
+ g_variant_get(value, "s", &name);
} else if (!g_strcmp0(key, "Class")) {
cod = g_variant_get_uint32(value);
} else if (!g_strcmp0(key, "Connected")) {
if ((paired == FALSE) && (trust == FALSE)) {
g_free(address);
+ g_free(alias);
g_free(name);
return BLUETOOTH_ERROR_NOT_PAIRED;
}
_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;
dev_info->connected = connected;
ret = BLUETOOTH_ERROR_NONE;
g_free(address);
+ g_free(alias);
g_free(name);
return ret;
void _bt_set_discovery_status(gboolean mode)
{
is_discovering = mode;
+ discovery_req = FALSE;
}
void _bt_set_cancel_by_user(gboolean value)
char *phone_name = NULL;
char *ptr = NULL;
- if (node == NULL)
- return;
+ ret_if(node == NULL);
if (vconf_keynode_get_type(node) == VCONF_TYPE_STRING) {
phone_name = vconf_keynode_get_str(node);
(const char **)&ptr))
*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");
}
}
_bt_adapter_set_status(BT_DEACTIVATED);
_bt_set_discovery_status(FALSE);
- if (TIZEN_FEATURE_BT_USB_DONGLE ||
- _bt_adapter_get_le_status() != BT_LE_DEACTIVATED) {
- /* Send disabled event */
- _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_DISABLED,
- g_variant_new("(i)", result));
- }
-
BT_INFO("Adapter disabled");
}
/* Send disabled event */
_bt_send_event(BT_LE_ADAPTER_EVENT, BLUETOOTH_EVENT_LE_DISABLED,
- g_variant_new("(i)", result));
+ g_variant_new("(i)", result));
}
void *_bt_get_adapter_agent(void)
BT_DBG("bt_state: (%s)", bt_le_status);
}
+static gboolean __bt_adapter_recovery_cb(gpointer data)
+{
+ int ret = 0;
+
+ BT_DBG("+");
+
+ recovery_timer = 0;
+
+ _bt_service_initialize();
+
+ ret = _bt_enable_adapter_check_status();
+ if (ret == BLUETOOTH_ERROR_NONE) {
+ ret = _bt_enable_adapter();
+ if (ret < 0)
+ BT_ERR("_bt_enable_adapter() failed");
+
+ ret = _bt_enable_adapter_le();
+ if (ret < 0)
+ BT_ERR("_bt_enable_adapter_le() failed");
+ }
+
+ recovery_cnt--;
+
+ BT_DBG("-");
+
+ return FALSE;
+}
+
void _bt_handle_adapter_added(void)
{
BT_DBG("+");
}
*/
+ recovery_cnt = -1;
+
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);
if (!TIZEN_FEATURE_BT_USB_DONGLE) {
adapter_agent = _bt_create_agent(BT_ADAPTER_AGENT_PATH, TRUE);
if (!adapter_agent) {
if (0 != ret)
ERR("vconf_ignore_key_changed failed\n");
-/* unregister all the services/servers/profiles registered on bluez-adapter
- once adapter is removed, reinitializing of the state-varaibles becomes
- a problem */
+ /* unregister all the services/servers/profiles registered on bluez-adapter
+ once adapter is removed, reinitializing of the state-varaibles becomes
+ a problem */
if (_bt_unregister_obex_server() != BLUETOOTH_ERROR_NONE)
BT_ERR("Fail to unregister obex server");
if (_bt_unregister_media_player() != BLUETOOTH_ERROR_NONE)
BT_ERR("Fail to unregister media player");
-/* Other unregister APIs should be placed here */
+ /* Other unregister APIs should be placed here */
if (!TIZEN_FEATURE_BT_USB_DONGLE) {
_bt_destroy_agent(adapter_agent);
adapter_agent = NULL;
- if (is_recovery_mode == TRUE) {
+ if (recovery_cnt > 0) {
/* Send disabled event */
_bt_set_disabled(BLUETOOTH_ERROR_NONE);
+ _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_DISABLED,
+ g_variant_new("(i)", 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);
+ if (recovery_timer > 0)
+ g_source_remove(recovery_timer);
+
+ if (TIZEN_PROFILE_WEARABLE) {
+ recovery_timer = g_timeout_add(BT_RECOVERY_TIME_W,
+ (GSourceFunc)__bt_adapter_recovery_cb, NULL);
+ } else {
+ recovery_timer = g_timeout_add(BT_RECOVERY_TIME,
+ (GSourceFunc)__bt_adapter_recovery_cb, NULL);
+ }
+
+ if (eventsystem_unregister_event(status_reg_id) != ES_R_OK)
+ BT_ERR("Fail to unregister system event");
+ return;
}
+
+ if (recovery_timer == 0)
+ _bt_reliable_terminate_service(NULL);
} else {
_bt_set_disabled(BLUETOOTH_ERROR_NONE);
+ _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_DISABLED,
+ g_variant_new("(i)", BLUETOOTH_ERROR_NONE));
}
if (eventsystem_unregister_event(status_reg_id) != ES_R_OK)
g_variant_unref(result);
_bt_set_disabled(BLUETOOTH_ERROR_TIMEOUT);
+ if (recovery_cnt > 0) {
+ BT_ERR("Try recovery again(remain:%d)", recovery_cnt);
+ if (recovery_timer > 0)
+ g_source_remove(recovery_timer);
+
+ if (TIZEN_PROFILE_WEARABLE) {
+ recovery_timer = g_timeout_add(BT_RECOVERY_TIME_W,
+ (GSourceFunc)__bt_adapter_recovery_cb, NULL);
+ } else {
+ recovery_timer = g_timeout_add(BT_RECOVERY_TIME,
+ (GSourceFunc)__bt_adapter_recovery_cb, NULL);
+ }
+
+ return FALSE;
+ }
+
if (!TIZEN_FEATURE_BT_USB_DONGLE)
_bt_terminate_service(NULL);
}
g_variant_unref(result);
- _bt_adapter_set_le_status(BT_LE_DEACTIVATED);
- _bt_set_le_disabled(BLUETOOTH_ERROR_TIMEOUT);
+ if (_bt_adapter_get_le_status() != BT_LE_DEACTIVATED)
+ _bt_set_le_disabled(BLUETOOTH_ERROR_TIMEOUT);
if (_bt_adapter_get_status() == BT_DEACTIVATED)
_bt_terminate_service(NULL);
return BLUETOOTH_ERROR_NONE;
}
+static gboolean __bt_set_powered(gboolean powered)
+{
+ GDBusProxy *proxy;
+ GError *error = NULL;
+ GVariant *result;
+
+ BT_DBG("");
+
+ proxy = _bt_get_adapter_properties_proxy();
+ retv_if(proxy == NULL, FALSE);
+
+ result = g_dbus_proxy_call_sync(proxy, "Set",
+ g_variant_new("(ssv)", BT_ADAPTER_INTERFACE, "Powered",
+ g_variant_new("b", powered)),
+ G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
+ if (!result) {
+ if (error != NULL) {
+ BT_ERR("Failed to set powered property (Error: %s)",
+ error->message);
+ g_clear_error(&error);
+ } else {
+ BT_ERR("Failed to set powered property");
+ }
+ return FALSE;
+ }
+
+ BT_INFO("Set powered [%d]", powered);
+ g_variant_unref(result);
+ return TRUE;
+}
+
static gboolean __bt_disconnect_all(void)
{
int i;
{
BT_DBG("");
_bt_set_disabled(BLUETOOTH_ERROR_NONE);
+ _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_DISABLED,
+ g_variant_new("(i)", BLUETOOTH_ERROR_NONE));
return FALSE;
}
{
BT_DBG("+");
int ret;
+ bt_le_status_t le_status;
if (_bt_adapter_get_status() == BT_DEACTIVATING) {
BT_DBG("Disabling in progress");
g_source_remove(timer_id);
timer_id = 0;
}
-/* unregister all the services/servers/profiles registered on bluez-adapter
- once adapter is removed, reinitializing of the state-varaibles becomes
- a problem */
+
+ /* unregister all the services/servers/profiles registered on bluez-adapter
+ once adapter is removed, reinitializing of the state-varaibles becomes
+ a problem */
if (_bt_unregister_obex_server() != BLUETOOTH_ERROR_NONE)
BT_ERR("Fail to unregister obex server");
if (_bt_unregister_media_player() != BLUETOOTH_ERROR_NONE)
BT_ERR("Fail to unregister media player");
+ /* Other unregister APIs should be placed here */
+
+ le_status = _bt_adapter_get_le_status();
+ if (le_status == BT_LE_ACTIVATED && is_le_intended == TRUE) {
+ __bt_disconnect_all();
+ } else {
+ if (le_status == BT_LE_ACTIVATED)
+ _bt_set_le_disabled(BLUETOOTH_ERROR_NONE);
+
+ __bt_set_powered(FALSE);
+ }
-/* Other unregister APIs should be placed here */
- __bt_disconnect_all();
ret = _bt_disable_cb();
BT_DBG("-");
int _bt_recover_adapter(void)
{
BT_DBG("+");
- GDBusProxy *proxy;
- GVariant *result;
- 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;
}
- _bt_adapter_set_status(BT_DEACTIVATING);
+ recovery_cnt = BT_RECOVERY_MAX_COUNT;
- proxy = __bt_get_core_proxy();
- retv_if(!proxy, BLUETOOTH_ERROR_INTERNAL);
-
- result = g_dbus_proxy_call_sync(proxy,
- "RecoverAdapter",
- NULL,
- G_DBUS_CALL_FLAGS_NONE,
- -1,
- NULL,
- &error);
-
- if (!result) {
- if (error != NULL) {
- BT_ERR("Failed to RecoverAdapter (Error: %s)", error->message);
- g_clear_error(&error);
- } else
- BT_ERR("Failed to RecoverAdapter");
- return BLUETOOTH_ERROR_INTERNAL;
- }
-
- is_recovery_mode = TRUE;
-
- g_variant_unref(result);
- __bt_disconnect_all();
+ _bt_disable_adapter();
+ _bt_disable_adapter_le();
BT_DBG("-");
return BLUETOOTH_ERROR_NONE;
if (status == BT_DEACTIVATING || le_status == BT_LE_DEACTIVATING) {
BT_ERR("Disabling in progress");
+ _bt_set_le_intended_status(FALSE);
return BLUETOOTH_ERROR_DEVICE_BUSY;
}
return BLUETOOTH_ERROR_INTERNAL;
}
- is_discovering = TRUE;
+ discovery_req = TRUE;
cancel_by_user = FALSE;
/* discovery status will be change in event */
g_variant_unref(result);
return BLUETOOTH_ERROR_INTERNAL;
}
- is_discovering = TRUE;
+ discovery_req = TRUE;
cancel_by_user = FALSE;
/* discovery status will be change in event */
g_variant_unref(result);
return ret;
}
+ discovery_req = FALSE;
cancel_by_user = TRUE;
/* discovery status will be change in event */
g_variant_unref(result);
gboolean _bt_is_discovering(void)
{
- return is_discovering;
+ return (is_discovering || discovery_req);
}
gboolean _bt_is_connectable(void)