Modify the privilege for battry RX / TX function
[platform/core/connectivity/bluetooth-frwk.git] / bt-service / bt-service-opp-client.c
index c0c7d08..3e83f72 100644 (file)
@@ -1,13 +1,11 @@
 /*
- * bluetooth-frwk
- *
- * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
+ * 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.
  * 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,
  *
  */
 
-#include <dbus/dbus-glib.h>
-#include <dbus/dbus.h>
 #include <glib.h>
 #include <dlog.h>
 #include <string.h>
+#include <mime_type.h>
+#include <aul.h>
+#include <glib.h>
+#include <gio/gio.h>
 
 #include "bluetooth-api.h"
 #include "bt-internal-types.h"
 #include "bt-service-util.h"
 #include "bt-service-opp-client.h"
 #include "bt-service-obex-agent.h"
+#include "bt-service-adapter.h"
 
-static BtObexAgent *opc_obex_agent = NULL;
-static GSList *transfer_list = NULL;
+#define BT_MIME_TYPE_MAX_LEN   20
 
+static GSList *transfer_list = NULL;
 bt_sending_info_t *sending_info;
+static int file_offset = 0;
 
-static gboolean __bt_release_callback(DBusGMethodInvocation *context,
-                                       gpointer user_data);
-
-static gboolean __bt_request_callback(DBusGMethodInvocation *context,
-                                       DBusGProxy *transfer,
-                                       gpointer user_data);
-
-static gboolean __bt_progress_callback(DBusGMethodInvocation *context,
-                                       DBusGProxy *transfer,
-                                       guint64 transferred,
-                                       gpointer user_data);
-
-static gboolean __bt_complete_callback(DBusGMethodInvocation *context,
-                                       DBusGProxy *transfer,
-                                       gpointer user_data);
-
-static gboolean __bt_error_callback(DBusGMethodInvocation *context,
-                                       DBusGProxy *transfer,
-                                       const char *message,
-                                       gpointer user_data);
-
+#define DBUS_TIEMOUT 20 * 1000  /* 20 Seconds */
+static gboolean __bt_sending_release();
+static int _bt_remove_session();
 
 static int __bt_opp_client_start_sending(int request_id, char *address,
-                                       char **file_name_array);
-
-static int __bt_opp_client_agent_init(void)
-{
-       opc_obex_agent = _bt_obex_agent_new();
-       retv_if(opc_obex_agent == NULL, BLUETOOTH_ERROR_INTERNAL);
-
-       _bt_obex_set_release_cb(opc_obex_agent,
-                                   __bt_release_callback, NULL);
-       _bt_obex_set_request_cb(opc_obex_agent,
-                                   __bt_request_callback, NULL);
-       _bt_obex_set_progress_cb(opc_obex_agent,
-                                    __bt_progress_callback, NULL);
-       _bt_obex_set_complete_cb(opc_obex_agent,
-                                    __bt_complete_callback, NULL);
-       _bt_obex_set_error_cb(opc_obex_agent,
-                               __bt_error_callback, NULL);
-
-       _bt_obex_setup(opc_obex_agent, BT_OBEX_CLIENT_AGENT_PATH);
-
-       return BLUETOOTH_ERROR_NONE;
-}
-
-static void __bt_opp_client_agent_deinit(void)
-{
-       ret_if(opc_obex_agent == NULL);
-
-       g_object_unref(opc_obex_agent);
-       opc_obex_agent = NULL;
-}
+                                       char **file_name_array, int file_count);
 
 static GQuark __bt_opc_error_quark(void)
 {
@@ -107,6 +62,10 @@ static void __bt_free_transfer_info(bt_transfer_info_t *info)
        if (info->proxy)
                g_object_unref(info->proxy);
 
+       if (info->properties_proxy)
+               g_object_unref(info->properties_proxy);
+
+
        g_free(info->transfer_name);
        g_free(info->file_name);
        g_free(info);
@@ -119,194 +78,239 @@ static void __bt_free_sending_info(bt_sending_info_t *info)
        /* Free the sending variable */
        __bt_free_transfer_info(info->transfer_info);
 
+       g_free(info->file_name_array);
+
        g_free(info->address);
        g_free(info);
 }
 
-static void __bt_value_free(GValue *value)
-{
-       g_value_unset(value);
-       g_free(value);
-}
-
 static gboolean __bt_cancel_push_cb(gpointer data)
 {
-       int result = BLUETOOTH_ERROR_CANCEL_BY_USER;
+       BT_DBG("+");
 
+       int result = BLUETOOTH_ERROR_CANCEL_BY_USER;
+       GVariant *param = NULL;
        retv_if(sending_info == NULL, FALSE);
+       sending_info->result = result;
 
+       param = g_variant_new("(isi)", result,
+                               sending_info->address,
+                               sending_info->request_id);
        /* Send the event in only error none case */
        _bt_send_event(BT_OPP_CLIENT_EVENT,
                        BLUETOOTH_EVENT_OPC_CONNECTED,
-                       DBUS_TYPE_INT32, &result,
-                       DBUS_TYPE_STRING, &sending_info->address,
-                       DBUS_TYPE_INT32, &sending_info->request_id,
-                       DBUS_TYPE_INVALID);
-
+                       param);
        __bt_free_sending_info(sending_info);
        sending_info = NULL;
 
-       __bt_opp_client_agent_deinit();
+       _bt_opp_client_event_deinit();
 
-       /* Operate remain works */
+       BT_DBG("Length of transfer list is %d", g_slist_length(transfer_list));
+
+        /*Operate remain works*/
        if (g_slist_length(transfer_list) > 0) {
                bt_sending_data_t *node = NULL;
 
                node = transfer_list->data;
                if (node == NULL) {
-                       BT_DBG("data is NULL");
+                       BT_ERR("data is NULL");
                        return FALSE;
                }
 
                transfer_list = g_slist_remove(transfer_list, node);
 
                if (__bt_opp_client_start_sending(node->request_id,
-                               node->address,
-                               node->file_path) != BLUETOOTH_ERROR_NONE) {
-                       BT_DBG("Fail to start sending");
+                               node->address, node->file_path,
+                               node->file_count) != BLUETOOTH_ERROR_NONE) {
+                       BT_ERR("Fail to start sending");
                }
        }
-
+       BT_DBG("-");
        return FALSE;
 }
 
-static gboolean __bt_progress_callback(DBusGMethodInvocation *context,
-                                       DBusGProxy *transfer,
-                                       guint64 transferred,
-                                       gpointer user_data)
+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;
-
-       dbus_g_method_return(context);
-
+       GVariant *param = NULL;
        retv_if(sending_info == NULL, TRUE);
        retv_if(sending_info->transfer_info == NULL, TRUE);
 
-       size = sending_info->transfer_info->size;
+       if (g_strcmp0(sending_info->transfer_info->transfer_path,
+                       transfer_path) != 0) {
+               BT_INFO("Path mismatch, previous transfer failed! Returning");
+               return FALSE;
+       }
 
+       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,
-                       DBUS_TYPE_INT32, &result,
-                       DBUS_TYPE_STRING, &sending_info->transfer_info->file_name,
-                       DBUS_TYPE_UINT64, &sending_info->transfer_info->size,
-                       DBUS_TYPE_INT32, &percentage_progress,
-                       DBUS_TYPE_INT32, &sending_info->request_id,
-                       DBUS_TYPE_INVALID);
+                       param);
+       BT_DBG("-");
 
        return TRUE;
 }
 
-static gboolean __bt_complete_callback(DBusGMethodInvocation *context,
-                                       DBusGProxy *transfer,
-                                       gpointer user_data)
+gboolean _bt_obex_client_completed(const char *transfer_path, gboolean success)
 {
+       BT_DBG("+");
+
        int result = BLUETOOTH_ERROR_NONE;
+       GVariant *param = NULL;
+       retv_if(sending_info == NULL, TRUE);
+       retv_if(sending_info->transfer_info == NULL, TRUE);
 
-       dbus_g_method_return(context);
+       if (g_strcmp0(sending_info->transfer_info->transfer_path,
+                       transfer_path) != 0) {
+               BT_INFO("Path mismatch, previous transfer failed! Returning");
+               return FALSE;
+       }
 
-       /* Send the event in only error none case */
-       _bt_send_event(BT_OPP_CLIENT_EVENT,
-                       BLUETOOTH_EVENT_OPC_TRANSFER_COMPLETE,
-                       DBUS_TYPE_INT32, &result,
-                       DBUS_TYPE_STRING, &sending_info->transfer_info->file_name,
-                       DBUS_TYPE_UINT64, &sending_info->transfer_info->size,
-                       DBUS_TYPE_INT32, &sending_info->request_id,
-                       DBUS_TYPE_INVALID);
+       result = (success == TRUE) ? BLUETOOTH_ERROR_NONE : BLUETOOTH_ERROR_CANCEL;
+
+       sending_info->transfer_info->transfer_status = BT_TRANSFER_STATUS_COMPLETED;
+       sending_info->result = result;
+
+       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("(issti)", result,
+                                               sending_info->address,
+                                               sending_info->transfer_info->file_name,
+                                               sending_info->transfer_info->size,
+                                               sending_info->request_id);
+                       _bt_send_event(BT_OPP_CLIENT_EVENT,
+                                       BLUETOOTH_EVENT_OPC_TRANSFER_COMPLETE,
+                                       param);
+                  __bt_free_transfer_info(sending_info->transfer_info);
+                  sending_info->transfer_info = NULL;
+                  /* Reset the file offset as we will cancelled remaining files also */
+                  file_offset = 0;
+               }
+               param = g_variant_new("(isi)", sending_info->result,
+                                       sending_info->address,
+                                       sending_info->request_id);
+               _bt_send_event(BT_OPP_CLIENT_EVENT,
+                               BLUETOOTH_EVENT_OPC_DISCONNECTED,
+                               param);
+               __bt_sending_release();
+               /* Sending info should not freed after sending_release it's
+                * already freed in that API and if any pending request is
+                * present then it recreate sending_info again.
+                * And if we free it here then CreateSession method call will
+                * made but RemoveSession method call will not done.
+                */
+       } else {
+               BT_DBG("complete success");
+               /* Send the event in only error none case */
+               param = g_variant_new("(issti)", result,
+                                       sending_info->address,
+                                       sending_info->transfer_info->file_name,
+                                       sending_info->transfer_info->size,
+                                       sending_info->request_id);
+               _bt_send_event(BT_OPP_CLIENT_EVENT,
+                               BLUETOOTH_EVENT_OPC_TRANSFER_COMPLETE,
+                               param);
+          __bt_free_transfer_info(sending_info->transfer_info);
+          sending_info->transfer_info = NULL;
+       }
+
+       BT_DBG("-");
 
        return TRUE;
 }
 
-static gboolean __bt_request_callback(DBusGMethodInvocation *context,
-                                       DBusGProxy *transfer,
-                                       gpointer user_data)
+gboolean _bt_obex_client_started(const char *transfer_path)
 {
-       GValue *value;
-       const char *transfer_name;
-       const char *file_name;
-       int size;
+       BT_DBG("+");
+
        int result = BLUETOOTH_ERROR_NONE;
-       GHashTable *hash = NULL;
-       GError *error;
+       GError *error = NULL;
+       GVariant *param = NULL;
+       GDBusConnection *g_conn;
+       GDBusProxy *properties_proxy;
+       GDBusProxy *transfer_proxy;
 
        if (sending_info == NULL || sending_info->is_canceled == TRUE) {
                result = BLUETOOTH_ERROR_CANCEL_BY_USER;
                goto canceled;
        }
 
-       dbus_g_method_return(context, "");
-
-       __bt_free_transfer_info(sending_info->transfer_info);
-
-       sending_info->transfer_info = g_malloc0(sizeof(bt_transfer_info_t));
-       sending_info->transfer_info->proxy = g_object_ref(transfer);
+       /* Get the session bus. */
+       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,
+                                               transfer_path, BT_PROPERTIES_INTERFACE,
+                                               NULL, &error);
 
-       dbus_g_proxy_call(transfer, "GetProperties", NULL,
-                               G_TYPE_INVALID,
-                               dbus_g_type_get_map("GHashTable", G_TYPE_STRING, G_TYPE_VALUE),
-                               &hash, G_TYPE_INVALID);
+       retv_if(properties_proxy == NULL, FALSE);
 
-       if (hash == NULL)
-               goto fail;
+       sending_info->transfer_info->properties_proxy = properties_proxy;
 
-       value = g_hash_table_lookup(hash, "Name");
-       transfer_name = value ? g_value_get_string(value) : NULL;
+       transfer_proxy = g_dbus_proxy_new_sync(g_conn, G_DBUS_PROXY_FLAGS_NONE,
+                                               NULL, BT_OBEXD_DBUS_NAME,
+                                               transfer_path, BT_OBEX_TRANSFER_INTERFACE,
+                                               NULL, &error);
 
-       value = g_hash_table_lookup(hash, "Filename");
-       file_name = value ? g_value_get_string(value) : NULL;
+       retv_if(transfer_proxy == NULL, FALSE);
 
-       value = g_hash_table_lookup(hash, "Size");
-       size = value ? g_value_get_uint64(value) : 0;
+       sending_info->transfer_info->proxy = transfer_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->result = BLUETOOTH_ERROR_NONE;
-
-       g_hash_table_destroy(hash);
+       sending_info->transfer_info->transfer_status = BT_TRANSFER_STATUS_STARTED;
+       sending_info->result = 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);
        _bt_send_event(BT_OPP_CLIENT_EVENT,
                        BLUETOOTH_EVENT_OPC_TRANSFER_STARTED,
-                       DBUS_TYPE_INT32, &result,
-                       DBUS_TYPE_STRING, &sending_info->transfer_info->file_name,
-                       DBUS_TYPE_UINT64, &sending_info->transfer_info->size,
-                       DBUS_TYPE_INT32, &sending_info->request_id,
-                       DBUS_TYPE_INVALID);
+                       param);
 
+       BT_DBG("-");
        return TRUE;
 canceled:
        error = g_error_new(__bt_opc_error_quark(), BT_OBEX_AGENT_ERROR_CANCEL,
                        "CancelledByUser");
 
-       dbus_g_method_return_error(context, error);
        g_error_free(error);
 
+       BT_DBG("-");
        return FALSE;
-fail:
-       result = BLUETOOTH_ERROR_INTERNAL;
-
-       /* Send the event in only error none case */
-       _bt_send_event(BT_OPP_CLIENT_EVENT,
-                       BLUETOOTH_EVENT_OPC_DISCONNECTED,
-                       DBUS_TYPE_INT32, &result,
-                       DBUS_TYPE_STRING, &sending_info->address,
-                       DBUS_TYPE_INT32, &sending_info->request_id,
-                       DBUS_TYPE_INVALID);
-
-       __bt_free_sending_info(sending_info);
-       sending_info = NULL;
-
-       __bt_opp_client_agent_deinit();
-
-       return TRUE;
 }
 
 static void __bt_free_sending_data(gpointer data)
@@ -316,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,25 +330,46 @@ static void __bt_free_sending_data(gpointer data)
        g_free(info);
 }
 
-static gboolean __bt_release_callback(DBusGMethodInvocation *context,
-                                       gpointer user_data)
+static void __bt_sending_release_cb(GDBusProxy *proxy,
+                               GAsyncResult *res, gpointer user_data)
 {
-       dbus_g_method_return(context);
+       BT_DBG("+");
+       ret_if(sending_info == NULL);
 
-       retv_if(sending_info == NULL, FALSE);
+       GError *error = NULL;
+       int result = BLUETOOTH_ERROR_NONE;
+       GVariant *param = NULL;
+       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);
+               g_error_free(error);
+
+               result = BLUETOOTH_ERROR_INTERNAL;
+       } else {
+               file_offset = 0;
+               BT_DBG("Session Removed");
+       }
+
+       sending_info->result = result;
+       param = g_variant_new("(isi)", sending_info->result,
+                               sending_info->address,
+                               sending_info->request_id);
        /* Send the event in only error none case */
        _bt_send_event(BT_OPP_CLIENT_EVENT,
                        BLUETOOTH_EVENT_OPC_DISCONNECTED,
-                       DBUS_TYPE_INT32, &sending_info->result,
-                       DBUS_TYPE_STRING, &sending_info->address,
-                       DBUS_TYPE_INT32, &sending_info->request_id,
-                       DBUS_TYPE_INVALID);
+                       param);
 
        __bt_free_sending_info(sending_info);
        sending_info = NULL;
 
-       __bt_opp_client_agent_deinit();
+       _bt_opp_client_event_deinit();
 
        /* Operate remain works */
        if (g_slist_length(transfer_list) > 0) {
@@ -357,122 +381,364 @@ static gboolean __bt_release_callback(DBusGMethodInvocation *context,
 
                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) != BLUETOOTH_ERROR_NONE) {
+                               data->address, data->file_path,
+                               data->file_count) != BLUETOOTH_ERROR_NONE) {
                        goto fail;
                }
        }
 
-       return TRUE;
+       return;
 fail:
        g_slist_free_full(transfer_list,
                                (GDestroyNotify)__bt_free_sending_data);
        transfer_list = NULL;
-       return TRUE;
+
+       BT_DBG("-");
+
+       return;
 }
 
-static gboolean __bt_error_callback(DBusGMethodInvocation *context,
-                                       DBusGProxy *transfer,
-                                       const char *message,
-                                       gpointer user_data)
+static int _bt_remove_session()
 {
-       int result;
+       GDBusConnection *g_conn;
+       GDBusProxy *session_proxy;
+       GError *err = NULL;
 
-       dbus_g_method_return(context);
+       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,
+                                               BT_OBEX_CLIENT_PATH,
+                                               BT_OBEX_CLIENT_INTERFACE,
+                                               NULL, &err);
+
+       retv_if(session_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
+
+       g_dbus_proxy_call(session_proxy, "RemoveSession",
+               g_variant_new("(o)", sending_info->session_path),
+               G_DBUS_CALL_FLAGS_NONE,
+               DBUS_TIEMOUT, NULL,
+               (GAsyncReadyCallback)__bt_sending_release_cb,
+               NULL);
+
+       return BLUETOOTH_ERROR_NONE;
+}
+
+static gboolean __bt_sending_release()
+{
+       BT_DBG("+");
 
        retv_if(sending_info == NULL, FALSE);
-       retv_if(sending_info->transfer_info == NULL, FALSE);
 
-       if (sending_info->is_canceled == TRUE)  {
-               result = BLUETOOTH_ERROR_CANCEL_BY_USER;
-       } else if (g_strcmp0(message, "Forbidden") == 0) {
-               result = BLUETOOTH_ERROR_ACCESS_DENIED;
-       } else if (g_str_has_prefix(message,
-               "Transport endpoint is not connected") == TRUE) {
-               result = BLUETOOTH_ERROR_NOT_CONNECTED;
-       } else if (g_strcmp0(message, "Database full") == 0) {
-               result = BLUETOOTH_ERROR_OUT_OF_MEMORY;
-       } else {
-               result = BLUETOOTH_ERROR_INTERNAL;
-       }
+       retv_if(_bt_remove_session() != BLUETOOTH_ERROR_NONE, FALSE);
 
-       sending_info->result = result;
+       BT_DBG("-");
+       return TRUE;
+}
 
-       /* Send the event in only error none case */
+void _bt_opc_disconnected(const char *session_path)
+{
+       BT_DBG("+");
+       GVariant *param = NULL;
+       ret_if(sending_info == NULL);
+
+       if (g_strcmp0(sending_info->session_path,
+                       session_path) != 0) {
+               BT_INFO("Path mismatch, previous transfer failed! Returning");
+               return;
+       }
+
+       if (sending_info->transfer_info) {
+               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("(issti)", sending_info->result,
+                                               sending_info->address,
+                                               sending_info->transfer_info->file_name,
+                                               sending_info->transfer_info->size,
+                                               sending_info->request_id);
+                       _bt_send_event(BT_OPP_CLIENT_EVENT,
+                                       BLUETOOTH_EVENT_OPC_TRANSFER_COMPLETE,
+                                       param);
+                       __bt_free_transfer_info(sending_info->transfer_info);
+               }
+       }
+       param = g_variant_new("(isi)", sending_info->result,
+                               sending_info->address,
+                               sending_info->request_id);
        _bt_send_event(BT_OPP_CLIENT_EVENT,
-                       BLUETOOTH_EVENT_OPC_TRANSFER_COMPLETE,
-                       DBUS_TYPE_INT32, &result,
-                       DBUS_TYPE_STRING, &sending_info->transfer_info->file_name,
-                       DBUS_TYPE_UINT64, &sending_info->transfer_info->size,
-                       DBUS_TYPE_INT32, &sending_info->request_id,
-                       DBUS_TYPE_INVALID);
-       return TRUE;
+                       BLUETOOTH_EVENT_OPC_DISCONNECTED,
+                       param);
+
+       __bt_free_sending_info(sending_info);
+       sending_info = NULL;
+
+       BT_DBG("-");
 }
 
-static void __bt_send_files_cb(DBusGProxy *proxy, DBusGProxyCall *call,
-                               void *user_data)
+static void __bt_send_file_cb(GDBusProxy *proxy,
+                               GAsyncResult *res, gpointer user_data)
 {
+       BT_DBG("+");
+       GVariant *value = NULL;
        GError *error = NULL;
+       char *session_path = NULL;
+       const char *transfer_name = NULL;
+       const char *file_name = NULL;
+       int size = 0;
+       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);
+               /* 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)
+               g_object_unref(proxy);
+
+       if (value) {
+               g_variant_get(value, "(oa{sv})", &session_path, &iter);
+               g_variant_unref(value);
+       }
+
+       __bt_free_transfer_info(sending_info->transfer_info);
+
+       sending_info->transfer_info = g_malloc0(sizeof(bt_transfer_info_t));
+
+       if (iter) {
+               const gchar *key;
+               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)
+                               file_name = g_variant_dup_string(val, &len);
+                       else if (g_strcmp0(key, "Size") == 0)
+                               size = g_variant_get_uint64(val);
+               }
+               g_variant_iter_free(iter);
+       }
+
+       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)
+{
+       BT_DBG("+");
+
+       GError *err = NULL;
+       GDBusConnection *g_conn;
+       GDBusProxy *client_proxy;
+       char mime_type[BT_MIME_TYPE_MAX_LEN + 1] = { 0 };
+
+       if (sending_info == NULL)
+               return;
+       if (file_offset < sending_info->file_count) {
+               /* Get the session bus. */
+               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,
+                                               NULL, BT_OBEXD_DBUS_NAME,
+                                               sending_info->session_path,
+                                               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");
+               g_dbus_proxy_call(client_proxy, "SendFile",
+                               g_variant_new("(ss)", sending_info->file_name_array[file_offset],
+                                                               mime_type),
+                               G_DBUS_CALL_FLAGS_NONE,
+                               DBUS_TIEMOUT, NULL,
+                               (GAsyncReadyCallback)__bt_send_file_cb,
+                               sending_info);
+               if (err != NULL) {
+                       BT_ERR("Calling SendFile failed: [%s]\n", err->message);
+                       g_clear_error(&err);
+                       return;
+               }
+
+       } else {
+               file_offset = 0;
+               __bt_sending_release();
+       }
+
+       BT_DBG("-");
+}
+
+static void __bt_create_session_cb(GDBusProxy *proxy,
+                               GAsyncResult *res, gpointer user_data)
+{
+       BT_DBG("+");
+
+       GError *error = NULL;
+       GVariant *value;
        int result = BLUETOOTH_ERROR_NONE;
+       char *session_path = NULL;
+       GVariant *param = NULL;
 
-       if (dbus_g_proxy_end_call(proxy, call, &error,
-                                       G_TYPE_INVALID) == FALSE) {
+       value = g_dbus_proxy_call_finish(proxy, res, &error);
+       if (value) {
+               g_variant_get(value, "(o)", &session_path);
+               g_variant_unref(value);
+       }
+       if (error) {
 
                BT_ERR("%s", error->message);
-               g_error_free(error);
+               g_clear_error(&error);
 
                result = BLUETOOTH_ERROR_INTERNAL;
+       } else {
+               BT_DBG("Session created");
+               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->sending_proxy = NULL;
-
+       sending_info->result = result;
+       param = g_variant_new("(isi)", result,
+                               sending_info->address,
+                               sending_info->request_id);
        /* Send the event in only error none case */
        _bt_send_event(BT_OPP_CLIENT_EVENT,
                        BLUETOOTH_EVENT_OPC_CONNECTED,
-                       DBUS_TYPE_INT32, &result,
-                       DBUS_TYPE_STRING, &sending_info->address,
-                       DBUS_TYPE_INT32, &sending_info->request_id,
-                       DBUS_TYPE_INVALID);
+                       param);
 
        if (result != BLUETOOTH_ERROR_NONE) {
+               BT_ERR("Calling __bt_sending_release");
+               gboolean ret = __bt_sending_release();
+
                __bt_free_sending_info(sending_info);
                sending_info = NULL;
+
+               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();
        }
+       BT_DBG("-");
+
 }
 
 static int __bt_opp_client_start_sending(int request_id, char *address,
-                                       char **file_name_array)
+                                       char **file_name_array, int file_count)
 {
-       GHashTable *hash;
-       GValue *value;
-       DBusGConnection *g_conn;
-       DBusGProxy *client_proxy;
-       DBusGProxyCall *proxy_call;
-       char *agent_path;
+       GVariantBuilder *builder;
+       int i;
+       GDBusConnection *g_conn;
+       GDBusProxy *client_proxy;
+       GError *error = NULL;
+       BT_DBG("+");
 
-       BT_CHECK_PARAMETER(address);
-       BT_CHECK_PARAMETER(file_name_array);
+       BT_CHECK_PARAMETER(address, return);
+       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 =  dbus_g_proxy_new_for_name(g_conn, BT_OBEX_SERVICE_NAME,
-                                       "/", BT_OBEX_CLIENT_INTERFACE);
+       client_proxy =  g_dbus_proxy_new_sync(g_conn, G_DBUS_PROXY_FLAGS_NONE,
+                                       NULL, BT_OBEX_SERVICE_NAME,
+                                       BT_OBEX_CLIENT_PATH,
+                                       BT_OBEX_CLIENT_INTERFACE,
+                                       NULL, &error);
+
+       if (error) {
+               BT_ERR("Unable to create client proxy: %s", error->message);
+               g_clear_error(&error);
+       }
 
        retv_if(client_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
 
-       hash = g_hash_table_new_full(g_str_hash, g_str_equal,
-                                    NULL, (GDestroyNotify)__bt_value_free);
+       builder = g_variant_builder_new(
+                               G_VARIANT_TYPE("a{sv}"));
 
-       value = g_new0(GValue, 1);
-       g_value_init(value, G_TYPE_STRING);
-       g_value_set_string(value, address);
-       g_hash_table_insert(hash, "Destination", value);
+       g_variant_builder_add(builder, "{sv}", "Target",
+               g_variant_new_string("OPP"));
 
        __bt_free_sending_info(sending_info);
 
@@ -480,60 +746,75 @@ static int __bt_opp_client_start_sending(int request_id, char *address,
        sending_info->address = g_strdup(address);
        sending_info->request_id = request_id;
 
-       __bt_opp_client_agent_deinit();
-       __bt_opp_client_agent_init();
-
-       agent_path = g_strdup(BT_OBEX_CLIENT_AGENT_PATH);
-
-       proxy_call = dbus_g_proxy_begin_call(client_proxy, "SendFiles",
-                               __bt_send_files_cb, NULL, NULL,
-                               dbus_g_type_get_map("GHashTable", G_TYPE_STRING,
-                                                   G_TYPE_VALUE), hash,
-                               G_TYPE_STRV, file_name_array,
-                               DBUS_TYPE_G_OBJECT_PATH, agent_path,
-                               G_TYPE_INVALID);
-
-       g_free(agent_path);
-
-       if (proxy_call == NULL) {
-                       BT_ERR("Fail to Send files");
-                       g_hash_table_destroy(hash);
-                       g_object_unref(client_proxy);
-                       __bt_free_sending_info(sending_info);
-                       __bt_opp_client_agent_deinit();
-                       sending_info = NULL;
-                       return BLUETOOTH_ERROR_INTERNAL;
+       sending_info->file_count = file_count;
+       sending_info->file_offset = 0;
+       sending_info->file_name_array = g_new0(char *, file_count + 1);
+
+       for (i = 0; i < file_count; i++) {
+               sending_info->file_name_array[i] = g_strdup(file_name_array[i]);
+               BT_DBG("file[%d]: %s", i, sending_info->file_name_array[i]);
        }
 
-       sending_info->sending_proxy = proxy_call;
-       g_hash_table_destroy(hash);
+       _bt_opp_client_event_deinit();
+       _bt_opp_client_event_init();
+       //_bt_obex_client_started(agent_path);
+
+       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("-");
 
        return BLUETOOTH_ERROR_NONE;
 }
 
-int _bt_opp_client_push_files(int request_id, DBusGMethodInvocation *context,
+int _bt_opp_client_push_files(int request_id, GDBusMethodInvocation *context,
                                bluetooth_device_address_t *remote_address,
                                char **file_path, int file_count)
 {
+       BT_DBG("+");
        char address[BT_ADDRESS_STRING_SIZE] = { 0 };
        bt_sending_data_t *data;
-       GArray *out_param1 = NULL;
-       GArray *out_param2 = NULL;
+
+       GVariant *out_param1 = NULL;
+
        int result = BLUETOOTH_ERROR_NONE;
        int i;
 
-       BT_CHECK_PARAMETER(remote_address);
-       BT_CHECK_PARAMETER(file_path);
+       BT_CHECK_PARAMETER(remote_address, return);
+       BT_CHECK_PARAMETER(file_path, return);
 
        /* Implement the queue */
        _bt_convert_addr_type_to_string(address, remote_address->addr);
 
        if (sending_info == NULL) {
                result = __bt_opp_client_start_sending(request_id,
-                                               address, file_path);
+                                               address, file_path, file_count);
+               if (result != BLUETOOTH_ERROR_NONE)
+                       return result;
        } else {
                /* Insert data in the queue */
                data = g_malloc0(sizeof(bt_sending_data_t));
+               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;
@@ -541,63 +822,80 @@ int _bt_opp_client_push_files(int request_id, DBusGMethodInvocation *context,
 
                for (i = 0; i < file_count; i++) {
                        data->file_path[i] = g_strdup(file_path[i]);
-                       BT_DBG("file[%d]: %s", i, data->file_path[i]);
+                       DBG_SECURE("file[%d]: %s", i, data->file_path[i]);
                }
 
                transfer_list = g_slist_append(transfer_list, data);
        }
 
-       out_param1 = g_array_new(FALSE, FALSE, sizeof(gchar));
-       out_param2 = g_array_new(FALSE, FALSE, sizeof(gchar));
+       out_param1 = g_variant_new_from_data((const GVariantType *)"ay",
+                                                       &request_id, sizeof(int),
+                                                       TRUE, NULL, NULL);
 
-       g_array_append_vals(out_param1, &request_id,
-                               sizeof(int));
-       g_array_append_vals(out_param2, &result, sizeof(int));
 
-       dbus_g_method_return(context, out_param1, out_param2);
+       g_dbus_method_invocation_return_value(context,
+                       g_variant_new("(iv)", result, out_param1));
 
-       g_array_free(out_param1, TRUE);
-       g_array_free(out_param2, TRUE);
+       BT_DBG("-");
 
        return result;
 }
 
 int _bt_opp_client_cancel_push(void)
 {
-       DBusGConnection *g_conn;
-       DBusGProxy *client_proxy;
+       BT_DBG("+");
 
+       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);
 
        sending_info->is_canceled = TRUE;
+       sending_info->result = result;
 
        if (sending_info->transfer_info) {
-               dbus_g_proxy_call_no_reply(sending_info->transfer_info->proxy,
-                                       "Cancel", G_TYPE_INVALID,
-                                       G_TYPE_INVALID);
-       } else {
-               retv_if(sending_info->sending_proxy == NULL,
-                                       BLUETOOTH_ERROR_INTERNAL);
 
-               g_conn = _bt_get_session_gconn();
-               retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
-
-               client_proxy =  dbus_g_proxy_new_for_name(g_conn, BT_OBEX_SERVICE_NAME,
-                                               "/", BT_OBEX_CLIENT_INTERFACE);
-
-               retv_if(client_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
+               ret = g_dbus_proxy_call_sync(sending_info->transfer_info->proxy,
+                                       "Cancel", NULL,
+                                       G_DBUS_CALL_FLAGS_NONE, -1,
+                                       NULL, &err);
+               if (ret == NULL) {
+                       if (err != NULL) {
+                               BT_ERR("Cancel Error: %s\n", err->message);
+                               g_error_free(err);
+                       }
+               } else {
+                       g_variant_unref(ret);
+               }
 
-               dbus_g_proxy_cancel_call(client_proxy,
-                                       sending_info->sending_proxy);
+               param = g_variant_new("(issti)", result,
+                                       sending_info->address,
+                                       sending_info->transfer_info->file_name,
+                                       sending_info->transfer_info->size,
+                                       sending_info->request_id);
+               _bt_send_event(BT_OPP_CLIENT_EVENT,
+                               BLUETOOTH_EVENT_OPC_TRANSFER_COMPLETE,
+                               param);
+
+               if (result == BLUETOOTH_ERROR_CANCEL_BY_USER) {
+                       BT_ERR("result is not BLUETOOTH_ERROR_NONE");
+                       __bt_sending_release();
+                       file_offset = 0;
+               }
 
+       } else {
                g_idle_add(__bt_cancel_push_cb, NULL);
        }
 
+       BT_DBG("-");
+
        return BLUETOOTH_ERROR_NONE;
 }
 
 int _bt_opp_client_cancel_all_transfers(void)
 {
+       BT_DBG("+");
        if (transfer_list) {
                g_slist_free_full(transfer_list,
                        (GDestroyNotify)__bt_free_sending_data);
@@ -606,15 +904,90 @@ int _bt_opp_client_cancel_all_transfers(void)
        }
 
        _bt_opp_client_cancel_push();
-
+       BT_DBG("-");
        return BLUETOOTH_ERROR_NONE;
 }
 
 int _bt_opp_client_is_sending(gboolean *sending)
 {
-       BT_CHECK_PARAMETER(sending);
+       BT_CHECK_PARAMETER(sending, return);
 
        *sending = sending_info ? TRUE : FALSE;
 
        return BLUETOOTH_ERROR_NONE;
 }
+
+void _bt_opp_client_check_pending_transfer(const char *address)
+{
+       BT_DBG("+");
+
+       int result = BLUETOOTH_ERROR_CANCEL;
+       GVariant *param = NULL;
+       ret_if(sending_info == NULL);
+       ret_if(sending_info->transfer_info == NULL);
+
+       if (g_strcmp0(sending_info->address, address) == 0) {
+               BT_INFO("Address Match.Cancel current transfer");
+               sending_info->transfer_info->transfer_status = BT_TRANSFER_STATUS_COMPLETED;
+               sending_info->result = result;
+
+               if (!sending_info->is_canceled) {
+                       param = g_variant_new("(issti)", result,
+                                               sending_info->address,
+                                               sending_info->transfer_info->file_name,
+                                               sending_info->transfer_info->size,
+                                               sending_info->request_id);
+                       _bt_send_event(BT_OPP_CLIENT_EVENT,
+                                       BLUETOOTH_EVENT_OPC_TRANSFER_COMPLETE,
+                                       param);
+                       __bt_free_transfer_info(sending_info->transfer_info);
+                       sending_info->transfer_info = NULL;
+                       /* Reset the file offset as we will cancelled remaining files also */
+                       file_offset = 0;
+               }
+               param = g_variant_new("(isi)", sending_info->result,
+                                       sending_info->address,
+                                       sending_info->request_id);
+               _bt_send_event(BT_OPP_CLIENT_EVENT,
+                               BLUETOOTH_EVENT_OPC_DISCONNECTED,
+                               param);
+
+               __bt_sending_release();
+       }
+       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);
+       }
+}