X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=bt-service%2Fbt-service-opp-client.c;h=a8d159bb3163f1cab1f24231c2549c7951938fd2;hb=6bf2f50e500ccb43eba4964023bf93fcc4649863;hp=74b1829868cd36ccf34414c91273604d212f0159;hpb=7640de5c091be29285bd031bcbd591aa14cf0d3e;p=platform%2Fcore%2Fconnectivity%2Fbluetooth-frwk.git diff --git a/bt-service/bt-service-opp-client.c b/bt-service/bt-service-opp-client.c index 74b1829..a8d159b 100644 --- a/bt-service/bt-service-opp-client.c +++ b/bt-service/bt-service-opp-client.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. @@ -25,7 +19,7 @@ #include #include #include - +#include #include #include @@ -37,6 +31,9 @@ #include "bt-service-util.h" #include "bt-service-opp-client.h" #include "bt-service-obex-agent.h" +#include "bt-service-adapter.h" + +#define BT_MIME_TYPE_MAX_LEN 20 static GSList *transfer_list = NULL; bt_sending_info_t *sending_info; @@ -44,7 +41,7 @@ static int file_offset = 0; #define DBUS_TIEMOUT 20 * 1000 /* 20 Seconds */ static gboolean __bt_sending_release(); -static void _bt_remove_session(); +static int _bt_remove_session(); static int __bt_opp_client_start_sending(int request_id, char *address, char **file_name_array, int file_count); @@ -132,12 +129,13 @@ static gboolean __bt_cancel_push_cb(gpointer data) return FALSE; } -gboolean _bt_obex_client_progress(const char *transfer_path, int transferred) +gboolean _bt_obex_client_progress(const char *transfer_path, guint64 transferred) { BT_DBG("+"); int percentage_progress; - gint64 size; + int previous_progress; + guint64 size; int result = BLUETOOTH_ERROR_NONE; GVariant *param = NULL; retv_if(sending_info == NULL, TRUE); @@ -150,22 +148,33 @@ gboolean _bt_obex_client_progress(const char *transfer_path, int transferred) } size = sending_info->transfer_info->size; - if (size != 0) - percentage_progress = (int)(((gdouble)transferred / - (gdouble)size) * 100); + percentage_progress = (int)(((gdouble)transferred /(gdouble)size) * 100); else percentage_progress = 0; sending_info->transfer_info->transfer_status = BT_TRANSFER_STATUS_PROGRESS; sending_info->result = result; + previous_progress = (int)(((gdouble)sending_info->transfer_info->progress /(gdouble)size) * 100); + if (percentage_progress == previous_progress && + sending_info->transfer_info->progress) { + sending_info->transfer_info->progress = transferred; + return TRUE; + } + BT_DBG("Sending progress [prev %d] [curr %d]", + previous_progress, percentage_progress); + + sending_info->transfer_info->progress = transferred; + /* Send the event in only error none case */ param = g_variant_new("(istii)", result, sending_info->transfer_info->file_name, sending_info->transfer_info->size, percentage_progress, sending_info->request_id); + + _bt_send_event(BT_OPP_CLIENT_EVENT, BLUETOOTH_EVENT_OPC_TRANSFER_PROGRESS, param); @@ -197,7 +206,8 @@ gboolean _bt_obex_client_completed(const char *transfer_path, gboolean success) if (!success) { /*In case of remote device reject, we need to send BLUETOOTH_EVENT_OPC_DISCONNECTED */ BT_DBG("completed with error"); if (!sending_info->is_canceled) { - param = g_variant_new("(isti)", result, + param = g_variant_new("(issti)", result, + sending_info->address, sending_info->transfer_info->file_name, sending_info->transfer_info->size, sending_info->request_id); @@ -225,7 +235,8 @@ gboolean _bt_obex_client_completed(const char *transfer_path, gboolean success) } else { BT_DBG("complete success"); /* Send the event in only error none case */ - param = g_variant_new("(isti)", result, + param = g_variant_new("(issti)", result, + sending_info->address, sending_info->transfer_info->file_name, sending_info->transfer_info->size, sending_info->request_id); @@ -258,10 +269,10 @@ gboolean _bt_obex_client_started(const char *transfer_path) } /* Get the session bus. */ - g_conn = _bt_get_session_gconn(); + g_conn = _bt_gdbus_get_session_gconn(); retv_if(g_conn == NULL, FALSE); properties_proxy = g_dbus_proxy_new_sync(g_conn, G_DBUS_PROXY_FLAGS_NONE, - NULL,BT_OBEXD_DBUS_NAME, + NULL, BT_OBEXD_DBUS_NAME, transfer_path, BT_PROPERTIES_INTERFACE, NULL, &error); @@ -280,7 +291,9 @@ gboolean _bt_obex_client_started(const char *transfer_path) sending_info->transfer_info->transfer_status = BT_TRANSFER_STATUS_STARTED; sending_info->result = result; - param = g_variant_new("(isti)", result, + + param = g_variant_new("(issti)", result, + sending_info->address, sending_info->transfer_info->file_name, sending_info->transfer_info->size, sending_info->request_id); @@ -307,9 +320,8 @@ static void __bt_free_sending_data(gpointer data) ret_if(info == NULL); - for (i = 0; i < info->file_count; i++) { + for (i = 0; i < info->file_count; i++) g_free(info->file_path[i]); - } _bt_delete_request_id(info->request_id); @@ -327,9 +339,13 @@ static void __bt_sending_release_cb(GDBusProxy *proxy, GError *error = NULL; int result = BLUETOOTH_ERROR_NONE; GVariant *param = NULL; - g_dbus_proxy_call_finish(proxy, res, &error); + GVariant *reply = NULL; + + reply = g_dbus_proxy_call_finish(proxy, res, &error); if (proxy) g_object_unref(proxy); + if (reply) + g_variant_unref(reply); if (error) { BT_ERR("%s", error->message); @@ -385,15 +401,15 @@ fail: return; } -static void _bt_remove_session() +static int _bt_remove_session() { GDBusConnection *g_conn; GDBusProxy *session_proxy; GError *err = NULL; - g_conn = _bt_get_session_gconn(); - ret_if(g_conn == NULL); - ret_if(sending_info->session_path == NULL); + g_conn = _bt_gdbus_get_session_gconn(); + retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL); + retv_if(sending_info->session_path == NULL, BLUETOOTH_ERROR_INVALID_PARAM); session_proxy = g_dbus_proxy_new_sync(g_conn, G_DBUS_PROXY_FLAGS_NONE, NULL, BT_OBEXD_DBUS_NAME, @@ -401,7 +417,7 @@ static void _bt_remove_session() BT_OBEX_CLIENT_INTERFACE, NULL, &err); - ret_if(session_proxy == NULL); + retv_if(session_proxy == NULL, BLUETOOTH_ERROR_INTERNAL); g_dbus_proxy_call(session_proxy, "RemoveSession", g_variant_new("(o)", sending_info->session_path), @@ -410,6 +426,7 @@ static void _bt_remove_session() (GAsyncReadyCallback)__bt_sending_release_cb, NULL); + return BLUETOOTH_ERROR_NONE; } static gboolean __bt_sending_release() @@ -418,7 +435,8 @@ static gboolean __bt_sending_release() retv_if(sending_info == NULL, FALSE); - _bt_remove_session(); + retv_if(_bt_remove_session() != BLUETOOTH_ERROR_NONE, FALSE); + BT_DBG("-"); return TRUE; } @@ -439,7 +457,8 @@ void _bt_opc_disconnected(const char *session_path) if (sending_info->transfer_info->transfer_status == BT_TRANSFER_STATUS_PROGRESS || sending_info->transfer_info->transfer_status == BT_TRANSFER_STATUS_STARTED) { BT_INFO("Abnormal termination"); - param = g_variant_new("(isti)", sending_info->result, + param = g_variant_new("(issti)", sending_info->result, + sending_info->address, sending_info->transfer_info->file_name, sending_info->transfer_info->size, sending_info->request_id); @@ -472,13 +491,41 @@ static void __bt_send_file_cb(GDBusProxy *proxy, const char *transfer_name = NULL; const char *file_name = NULL; int size = 0; - GVariantIter *iter; + GVariantIter *iter = NULL; value = g_dbus_proxy_call_finish(proxy, res, &error); if (error) { + g_dbus_error_strip_remote_error(error); BT_ERR("%s", error->message); - g_error_free(error); - if (proxy) - g_object_unref(proxy); + /* If Obex is not able to open a file then continue with other if any */ + if (g_strcmp0("Unable to open file", error->message) == 0) { + GVariant *param = NULL; + gint64 size = 0; + + BT_ERR("Unable to open file [%s]", sending_info->file_name_array[file_offset]); + + param = g_variant_new("(issti)", BLUETOOTH_ERROR_NOT_FOUND, + sending_info->address, + sending_info->file_name_array[file_offset], + size, + sending_info->request_id); + _bt_send_event(BT_OPP_CLIENT_EVENT, + BLUETOOTH_EVENT_OPC_TRANSFER_STARTED, + param); + + param = g_variant_new("(issti)", BLUETOOTH_ERROR_NOT_FOUND, + sending_info->address, + sending_info->file_name_array[file_offset], + size, + sending_info->request_id); + _bt_send_event(BT_OPP_CLIENT_EVENT, + BLUETOOTH_EVENT_OPC_TRANSFER_COMPLETE, + param); + g_error_free(error); + if (proxy) + g_object_unref(proxy); + file_offset++; + _bt_sending_files(); + } return; } if (proxy) @@ -498,13 +545,12 @@ static void __bt_send_file_cb(GDBusProxy *proxy, GVariant *val; gsize len = 0; while (g_variant_iter_loop(iter, "{sv}", &key, &val)) { - if (g_strcmp0(key, "Name") == 0) { - transfer_name = g_variant_dup_string(val,&len); - } else if (g_strcmp0(key, "Filename") == 0) { + if (g_strcmp0(key, "Name") == 0) + transfer_name = g_variant_dup_string(val, &len); + else if (g_strcmp0(key, "Filename") == 0) file_name = g_variant_dup_string(val, &len); - } else if (g_strcmp0(key, "Size") == 0) { + else if (g_strcmp0(key, "Size") == 0) size = g_variant_get_uint64(val); - } } g_variant_iter_free(iter); } @@ -512,11 +558,14 @@ static void __bt_send_file_cb(GDBusProxy *proxy, sending_info->transfer_info->transfer_name = g_strdup(transfer_name); sending_info->transfer_info->file_name = g_strdup(file_name); sending_info->transfer_info->size = size; + sending_info->transfer_info->progress = 0; sending_info->transfer_info->transfer_path = session_path; sending_info->transfer_info->transfer_status = BT_TRANSFER_STATUS_QUEUED; sending_info->result = BLUETOOTH_ERROR_NONE; file_offset++; + g_free((gchar *)transfer_name); + g_free((gchar *)file_name); } void _bt_sending_files(void) @@ -526,14 +575,13 @@ void _bt_sending_files(void) GError *err = NULL; GDBusConnection *g_conn; GDBusProxy *client_proxy; - char *mimetype = NULL; - char *ext = NULL; + char mime_type[BT_MIME_TYPE_MAX_LEN + 1] = { 0 }; if (sending_info == NULL) return; - if (file_offset < sending_info->file_count){ + if (file_offset < sending_info->file_count) { /* Get the session bus. */ - g_conn = _bt_get_session_gconn(); + g_conn = _bt_gdbus_get_session_gconn(); ret_if(g_conn == NULL); client_proxy = g_dbus_proxy_new_sync(g_conn, G_DBUS_PROXY_FLAGS_NONE, @@ -542,15 +590,27 @@ void _bt_sending_files(void) BT_OBEX_OBJECT_PUSH_INTERFACE, NULL, &err); ret_if(client_proxy == NULL); + if (aul_get_mime_from_file(sending_info->file_name_array[file_offset], + mime_type, BT_MIME_TYPE_MAX_LEN) == AUL_R_OK) { + BT_DBG("MLME type = %s", mime_type); + + /* For IOPT compliance, change "text/x-iMelody" to "audio/imelody" + * because few devices(multimedia players) reject the OPP put for text objects + * since they support only multimedia files exchange */ + if (!strcasecmp(mime_type, "text/x-iMelody")) { + strncpy(mime_type, "audio/imelody", BT_MIME_TYPE_MAX_LEN); + BT_DBG("over writing mime type to = %s", mime_type); + } + if (!strcasecmp(mime_type, "text/vcard")) { + strncpy(mime_type, "text/x-vcard", BT_MIME_TYPE_MAX_LEN); + BT_DBG("over writing mime type to = %s", mime_type); + } + } BT_DBG("Calling SendFile"); - ext = strrchr(sending_info->file_name_array[file_offset], '.'); - - if (ext != NULL && (!strcmp(ext, ".imy"))) - mimetype = g_strdup("audio/imelody"); g_dbus_proxy_call(client_proxy, "SendFile", g_variant_new("(ss)", sending_info->file_name_array[file_offset], - mimetype), + mime_type), G_DBUS_CALL_FLAGS_NONE, DBUS_TIEMOUT, NULL, (GAsyncReadyCallback)__bt_send_file_cb, @@ -558,12 +618,10 @@ void _bt_sending_files(void) if (err != NULL) { BT_ERR("Calling SendFile failed: [%s]\n", err->message); g_clear_error(&err); - g_free(mimetype); return; } - g_free(mimetype); - }else{ + } else { file_offset = 0; __bt_sending_release(); } @@ -583,9 +641,6 @@ static void __bt_create_session_cb(GDBusProxy *proxy, GVariant *param = NULL; value = g_dbus_proxy_call_finish(proxy, res, &error); - if (proxy) - g_object_unref(proxy); - if (value) { g_variant_get(value, "(o)", &session_path); g_variant_unref(value); @@ -596,12 +651,13 @@ static void __bt_create_session_cb(GDBusProxy *proxy, g_clear_error(&error); result = BLUETOOTH_ERROR_INTERNAL; - }else{ + } else { BT_DBG("Session created"); - if(sending_info != NULL) + if (sending_info != NULL) sending_info->session_path = g_strdup(session_path); } g_free(session_path); + g_object_unref(proxy); ret_if(sending_info == NULL); sending_info->result = result; @@ -615,11 +671,32 @@ static void __bt_create_session_cb(GDBusProxy *proxy, if (result != BLUETOOTH_ERROR_NONE) { BT_ERR("Calling __bt_sending_release"); - __bt_sending_release(); + gboolean ret = __bt_sending_release(); __bt_free_sending_info(sending_info); sending_info = NULL; - }else { + + if (ret == FALSE) { + BT_DBG("ReleaseSession Not called"); + /* Operate remain works */ + if (g_slist_length(transfer_list) > 0) { + bt_sending_data_t *data = NULL; + + data = transfer_list->data; + ret_if(data == NULL); + + transfer_list = g_slist_remove(transfer_list, data); + + BT_DBG("calling __bt_opp_client_start_sending"); + + if (__bt_opp_client_start_sending(data->request_id, + data->address, data->file_path, + data->file_count) != BLUETOOTH_ERROR_NONE) { + BT_ERR("Sending Enqueued Transfer Failed"); + } + } + } + } else { BT_DBG("Calling sending_files"); _bt_sending_files(); } @@ -641,7 +718,7 @@ static int __bt_opp_client_start_sending(int request_id, char *address, BT_CHECK_PARAMETER(file_name_array, return); /* Get the session bus. */ - g_conn = _bt_get_session_gconn(); + g_conn = _bt_gdbus_get_session_gconn(); retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL); client_proxy = g_dbus_proxy_new_sync(g_conn, G_DBUS_PROXY_FLAGS_NONE, @@ -682,14 +759,25 @@ static int __bt_opp_client_start_sending(int request_id, char *address, _bt_opp_client_event_init(); //_bt_obex_client_started(agent_path); - BT_DBG("Going to call CreateSession"); - - g_dbus_proxy_call(client_proxy, "CreateSession", + BT_DBG("Adapter Status %d", _bt_adapter_get_status()); + if (_bt_adapter_get_status() == BT_ACTIVATED) { + BT_DBG("Going to call CreateSession"); + g_dbus_proxy_call(client_proxy, "CreateSession", g_variant_new("(sa{sv})", address, builder), G_DBUS_CALL_FLAGS_NONE, DBUS_TIEMOUT, NULL, (GAsyncReadyCallback)__bt_create_session_cb, NULL); + } else { + GVariant *param = g_variant_new("(isi)", BLUETOOTH_ERROR_INTERNAL, + sending_info->address, sending_info->request_id); + + BT_DBG("Address[%s] RequestID[%d]", sending_info->address, sending_info->request_id); + _bt_send_event(BT_OPP_CLIENT_EVENT, BLUETOOTH_EVENT_OPC_CONNECTED, + param); + __bt_free_sending_info(sending_info); + sending_info = NULL; + } g_variant_builder_unref(builder); BT_DBG("-"); @@ -724,10 +812,6 @@ int _bt_opp_client_push_files(int request_id, GDBusMethodInvocation *context, } else { /* Insert data in the queue */ data = g_malloc0(sizeof(bt_sending_data_t)); - /* Fix : NULL_RETURNS */ - if (data == NULL) - return BLUETOOTH_ERROR_MEMORY_ALLOCATION; - data->file_path = g_new0(char *, file_count + 1); data->address = g_strdup(address); data->file_count = file_count; @@ -760,6 +844,7 @@ int _bt_opp_client_cancel_push(void) GError *err = NULL; int result = BLUETOOTH_ERROR_CANCEL_BY_USER; + GVariant *ret = NULL; GVariant *param = NULL; retv_if(sending_info == NULL, BLUETOOTH_ERROR_NOT_IN_OPERATION); @@ -768,11 +853,21 @@ int _bt_opp_client_cancel_push(void) if (sending_info->transfer_info) { - g_dbus_proxy_call_sync(sending_info->transfer_info->proxy, + ret = g_dbus_proxy_call_sync(sending_info->transfer_info->proxy, "Cancel", NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err); - param = g_variant_new("(isti)", result, + if (ret == NULL) { + if (err != NULL) { + BT_ERR("Cancel Error: %s\n", err->message); + g_error_free(err); + } + } else { + g_variant_unref(ret); + } + + param = g_variant_new("(issti)", result, + sending_info->address, sending_info->transfer_info->file_name, sending_info->transfer_info->size, sending_info->request_id); @@ -834,7 +929,8 @@ void _bt_opp_client_check_pending_transfer(const char *address) sending_info->result = result; if (!sending_info->is_canceled) { - param = g_variant_new("(isti)", result, + param = g_variant_new("(issti)", result, + sending_info->address, sending_info->transfer_info->file_name, sending_info->transfer_info->size, sending_info->request_id); @@ -857,3 +953,38 @@ void _bt_opp_client_check_pending_transfer(const char *address) } BT_DBG("-"); } + +int _bt_opp_get_client_progress(guint8 *progress) +{ + if (sending_info == NULL || sending_info->transfer_info == NULL) { + BT_ERR("No Active Outbound transfer"); + return BLUETOOTH_ERROR_NOT_FOUND; + } + + *progress = (int)(((double)sending_info->transfer_info->progress / + sending_info->transfer_info->size) * 100); + + BT_DBG("Percentage: %d", *progress); + return BLUETOOTH_ERROR_NONE; +} + +void _bt_cancel_queued_transfers(void) +{ + bt_sending_data_t *data = NULL; + GVariant *param = NULL; + + BT_INFO("Cancel queued Transfers:: Length of transfer list is %d", + g_slist_length(transfer_list)); + + while (transfer_list) { + data = transfer_list->data; + param = g_variant_new("(isi)", BLUETOOTH_ERROR_INTERNAL, + data->address, data->request_id); + + BT_DBG("Address[%s] RequestID[%d]", data->address, data->request_id); + _bt_send_event(BT_OPP_CLIENT_EVENT, BLUETOOTH_EVENT_OPC_CONNECTED, + param); + + transfer_list = g_slist_remove(transfer_list, data); + } +}