#include <dlog.h>
#include <string.h>
#include <mime_type.h>
-
+#include <aul.h>
#include <glib.h>
#include <gio/gio.h>
#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;
#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);
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);
}
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);
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);
} 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);
}
/* 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,
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);
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);
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);
BT_DBG("Session Removed");
}
- if (sending_info->result != BLUETOOTH_ERROR_CANCEL_BY_USER)
- sending_info->result = result;
-
+ sending_info->result = result;
param = g_variant_new("(isi)", sending_info->result,
sending_info->address,
sending_info->request_id);
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,
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),
(GAsyncReadyCallback)__bt_sending_release_cb,
NULL);
+ return BLUETOOTH_ERROR_NONE;
}
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;
}
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);
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)
GVariant *val;
gsize len = 0;
while (g_variant_iter_loop(iter, "{sv}", &key, &val)) {
- if (g_strcmp0(key, "Name") == 0) {
+ if (g_strcmp0(key, "Name") == 0)
transfer_name = g_variant_dup_string(val, &len);
- } else if (g_strcmp0(key, "Filename") == 0) {
+ 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);
}
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)
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) {
/* 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,
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,
if (err != NULL) {
BT_ERR("Calling SendFile failed: [%s]\n", err->message);
g_clear_error(&err);
- g_free(mimetype);
return;
}
- g_free(mimetype);
} else {
file_offset = 0;
__bt_sending_release();
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);
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;
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;
+
+ 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_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,
_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("-");
} 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;
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);
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);
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);
}
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);
+ }
+}