2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
21 #include <mime_type.h>
25 #include "bluetooth-api.h"
26 #include "bt-internal-types.h"
28 #include "bt-service-common.h"
29 #include "bt-service-event.h"
30 #include "bt-service-util.h"
31 #include "bt-service-opp-client.h"
32 #include "bt-service-obex-agent.h"
33 #include "bt-service-adapter.h"
35 #define BT_MIME_TYPE_MAX_LEN 20
37 static GSList *transfer_list = NULL;
38 bt_sending_info_t *sending_info;
39 static int file_offset = 0;
41 #define DBUS_TIEMOUT 20 * 1000 /* 20 Seconds */
42 static gboolean __bt_sending_release();
43 static int _bt_remove_session();
45 static int __bt_opp_client_start_sending(int request_id, char *address,
46 char **file_name_array, int file_count);
48 static GQuark __bt_opc_error_quark(void)
50 static GQuark quark = 0;
52 quark = g_quark_from_static_string("agent");
57 static void __bt_free_transfer_info(bt_transfer_info_t *info)
62 g_object_unref(info->proxy);
64 if (info->properties_proxy)
65 g_object_unref(info->properties_proxy);
68 g_free(info->transfer_name);
69 g_free(info->file_name);
73 static void __bt_free_sending_info(bt_sending_info_t *info)
77 /* Free the sending variable */
78 __bt_free_transfer_info(info->transfer_info);
80 g_free(info->file_name_array);
82 g_free(info->address);
86 static gboolean __bt_cancel_push_cb(gpointer data)
90 int result = BLUETOOTH_ERROR_CANCEL_BY_USER;
91 GVariant *param = NULL;
92 retv_if(sending_info == NULL, FALSE);
93 sending_info->result = result;
95 param = g_variant_new("(isi)", result,
96 sending_info->address,
97 sending_info->request_id);
98 /* Send the event in only error none case */
99 _bt_send_event(BT_OPP_CLIENT_EVENT,
100 BLUETOOTH_EVENT_OPC_CONNECTED,
102 __bt_free_sending_info(sending_info);
105 _bt_opp_client_event_deinit();
107 BT_DBG("Length of transfer list is %d", g_slist_length(transfer_list));
109 /*Operate remain works*/
110 if (g_slist_length(transfer_list) > 0) {
111 bt_sending_data_t *node = NULL;
113 node = transfer_list->data;
115 BT_ERR("data is NULL");
119 transfer_list = g_slist_remove(transfer_list, node);
121 if (__bt_opp_client_start_sending(node->request_id,
122 node->address, node->file_path,
123 node->file_count) != BLUETOOTH_ERROR_NONE) {
124 BT_ERR("Fail to start sending");
131 gboolean _bt_obex_client_progress(const char *transfer_path, guint64 transferred)
135 int percentage_progress;
136 int previous_progress;
138 int result = BLUETOOTH_ERROR_NONE;
139 GVariant *param = NULL;
140 retv_if(sending_info == NULL, TRUE);
141 retv_if(sending_info->transfer_info == NULL, TRUE);
143 if (g_strcmp0(sending_info->transfer_info->transfer_path,
144 transfer_path) != 0) {
145 BT_INFO("Path mismatch, previous transfer failed! Returning");
149 size = sending_info->transfer_info->size;
151 percentage_progress = (int)(((gdouble)transferred /(gdouble)size) * 100);
153 percentage_progress = 0;
155 sending_info->transfer_info->transfer_status = BT_TRANSFER_STATUS_PROGRESS;
156 sending_info->result = result;
158 previous_progress = (int)(((gdouble)sending_info->transfer_info->progress /(gdouble)size) * 100);
159 if (percentage_progress == previous_progress &&
160 sending_info->transfer_info->progress) {
161 sending_info->transfer_info->progress = transferred;
164 BT_DBG("Sending progress [prev %d] [curr %d]",
165 previous_progress, percentage_progress);
167 sending_info->transfer_info->progress = transferred;
169 /* Send the event in only error none case */
170 param = g_variant_new("(istii)", result,
171 sending_info->transfer_info->file_name,
172 sending_info->transfer_info->size,
174 sending_info->request_id);
177 _bt_send_event(BT_OPP_CLIENT_EVENT,
178 BLUETOOTH_EVENT_OPC_TRANSFER_PROGRESS,
185 gboolean _bt_obex_client_completed(const char *transfer_path, gboolean success)
189 int result = BLUETOOTH_ERROR_NONE;
190 GVariant *param = NULL;
191 retv_if(sending_info == NULL, TRUE);
192 retv_if(sending_info->transfer_info == NULL, TRUE);
194 if (g_strcmp0(sending_info->transfer_info->transfer_path,
195 transfer_path) != 0) {
196 BT_INFO("Path mismatch, previous transfer failed! Returning");
200 result = (success == TRUE) ? BLUETOOTH_ERROR_NONE : BLUETOOTH_ERROR_CANCEL;
202 sending_info->transfer_info->transfer_status = BT_TRANSFER_STATUS_COMPLETED;
203 sending_info->result = result;
205 if (!success) { /*In case of remote device reject, we need to send BLUETOOTH_EVENT_OPC_DISCONNECTED */
206 BT_DBG("completed with error");
207 if (!sending_info->is_canceled) {
208 param = g_variant_new("(issti)", result,
209 sending_info->address,
210 sending_info->transfer_info->file_name,
211 sending_info->transfer_info->size,
212 sending_info->request_id);
213 _bt_send_event(BT_OPP_CLIENT_EVENT,
214 BLUETOOTH_EVENT_OPC_TRANSFER_COMPLETE,
216 __bt_free_transfer_info(sending_info->transfer_info);
217 sending_info->transfer_info = NULL;
218 /* Reset the file offset as we will cancelled remaining files also */
221 param = g_variant_new("(isi)", sending_info->result,
222 sending_info->address,
223 sending_info->request_id);
224 _bt_send_event(BT_OPP_CLIENT_EVENT,
225 BLUETOOTH_EVENT_OPC_DISCONNECTED,
227 __bt_sending_release();
228 /* Sending info should not freed after sending_release it's
229 * already freed in that API and if any pending request is
230 * present then it recreate sending_info again.
231 * And if we free it here then CreateSession method call will
232 * made but RemoveSession method call will not done.
235 BT_DBG("complete success");
236 /* Send the event in only error none case */
237 param = g_variant_new("(issti)", result,
238 sending_info->address,
239 sending_info->transfer_info->file_name,
240 sending_info->transfer_info->size,
241 sending_info->request_id);
242 _bt_send_event(BT_OPP_CLIENT_EVENT,
243 BLUETOOTH_EVENT_OPC_TRANSFER_COMPLETE,
245 __bt_free_transfer_info(sending_info->transfer_info);
246 sending_info->transfer_info = NULL;
254 gboolean _bt_obex_client_started(const char *transfer_path)
258 int result = BLUETOOTH_ERROR_NONE;
259 GError *error = NULL;
260 GVariant *param = NULL;
261 GDBusConnection *g_conn;
262 GDBusProxy *properties_proxy;
263 GDBusProxy *transfer_proxy;
265 if (sending_info == NULL || sending_info->is_canceled == TRUE) {
266 result = BLUETOOTH_ERROR_CANCEL_BY_USER;
270 /* Get the session bus. */
271 g_conn = _bt_gdbus_get_session_gconn();
272 retv_if(g_conn == NULL, FALSE);
273 properties_proxy = g_dbus_proxy_new_sync(g_conn, G_DBUS_PROXY_FLAGS_NONE,
274 NULL, BT_OBEXD_DBUS_NAME,
275 transfer_path, BT_PROPERTIES_INTERFACE,
278 retv_if(properties_proxy == NULL, FALSE);
280 sending_info->transfer_info->properties_proxy = properties_proxy;
282 transfer_proxy = g_dbus_proxy_new_sync(g_conn, G_DBUS_PROXY_FLAGS_NONE,
283 NULL, BT_OBEXD_DBUS_NAME,
284 transfer_path, BT_OBEX_TRANSFER_INTERFACE,
287 retv_if(transfer_proxy == NULL, FALSE);
289 sending_info->transfer_info->proxy = transfer_proxy;
291 sending_info->transfer_info->transfer_status = BT_TRANSFER_STATUS_STARTED;
292 sending_info->result = result;
294 param = g_variant_new("(issti)", result,
295 sending_info->address,
296 sending_info->transfer_info->file_name,
297 sending_info->transfer_info->size,
298 sending_info->request_id);
299 _bt_send_event(BT_OPP_CLIENT_EVENT,
300 BLUETOOTH_EVENT_OPC_TRANSFER_STARTED,
306 error = g_error_new(__bt_opc_error_quark(), BT_OBEX_AGENT_ERROR_CANCEL,
315 static void __bt_free_sending_data(gpointer data)
318 bt_sending_data_t *info = data;
320 ret_if(info == NULL);
322 for (i = 0; i < info->file_count; i++)
323 g_free(info->file_path[i]);
325 _bt_delete_request_id(info->request_id);
327 g_free(info->file_path);
328 g_free(info->address);
332 static void __bt_sending_release_cb(GDBusProxy *proxy,
333 GAsyncResult *res, gpointer user_data)
336 ret_if(sending_info == NULL);
338 GError *error = NULL;
339 int result = BLUETOOTH_ERROR_NONE;
340 GVariant *param = NULL;
341 GVariant *reply = NULL;
343 reply = g_dbus_proxy_call_finish(proxy, res, &error);
345 g_object_unref(proxy);
347 g_variant_unref(reply);
350 BT_ERR("%s", error->message);
353 result = BLUETOOTH_ERROR_INTERNAL;
356 BT_DBG("Session Removed");
359 sending_info->result = result;
360 param = g_variant_new("(isi)", sending_info->result,
361 sending_info->address,
362 sending_info->request_id);
363 /* Send the event in only error none case */
364 _bt_send_event(BT_OPP_CLIENT_EVENT,
365 BLUETOOTH_EVENT_OPC_DISCONNECTED,
368 __bt_free_sending_info(sending_info);
371 _bt_opp_client_event_deinit();
373 /* Operate remain works */
374 if (g_slist_length(transfer_list) > 0) {
375 bt_sending_data_t *data = NULL;
377 data = transfer_list->data;
381 transfer_list = g_slist_remove(transfer_list, data);
383 BT_DBG("calling __bt_opp_client_start_sending");
385 if (__bt_opp_client_start_sending(data->request_id,
386 data->address, data->file_path,
387 data->file_count) != BLUETOOTH_ERROR_NONE) {
394 g_slist_free_full(transfer_list,
395 (GDestroyNotify)__bt_free_sending_data);
396 transfer_list = NULL;
403 static int _bt_remove_session()
405 GDBusConnection *g_conn;
406 GDBusProxy *session_proxy;
409 g_conn = _bt_gdbus_get_session_gconn();
410 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
411 retv_if(sending_info->session_path == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
413 session_proxy = g_dbus_proxy_new_sync(g_conn, G_DBUS_PROXY_FLAGS_NONE,
414 NULL, BT_OBEXD_DBUS_NAME,
416 BT_OBEX_CLIENT_INTERFACE,
419 retv_if(session_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
421 g_dbus_proxy_call(session_proxy, "RemoveSession",
422 g_variant_new("(o)", sending_info->session_path),
423 G_DBUS_CALL_FLAGS_NONE,
425 (GAsyncReadyCallback)__bt_sending_release_cb,
428 return BLUETOOTH_ERROR_NONE;
431 static gboolean __bt_sending_release()
435 retv_if(sending_info == NULL, FALSE);
437 retv_if(_bt_remove_session() != BLUETOOTH_ERROR_NONE, FALSE);
443 void _bt_opc_disconnected(const char *session_path)
446 GVariant *param = NULL;
447 ret_if(sending_info == NULL);
449 if (g_strcmp0(sending_info->session_path,
450 session_path) != 0) {
451 BT_INFO("Path mismatch, previous transfer failed! Returning");
455 if (sending_info->transfer_info) {
456 if (sending_info->transfer_info->transfer_status == BT_TRANSFER_STATUS_PROGRESS ||
457 sending_info->transfer_info->transfer_status == BT_TRANSFER_STATUS_STARTED) {
458 BT_INFO("Abnormal termination");
459 param = g_variant_new("(issti)", sending_info->result,
460 sending_info->address,
461 sending_info->transfer_info->file_name,
462 sending_info->transfer_info->size,
463 sending_info->request_id);
464 _bt_send_event(BT_OPP_CLIENT_EVENT,
465 BLUETOOTH_EVENT_OPC_TRANSFER_COMPLETE,
467 __bt_free_transfer_info(sending_info->transfer_info);
470 param = g_variant_new("(isi)", sending_info->result,
471 sending_info->address,
472 sending_info->request_id);
473 _bt_send_event(BT_OPP_CLIENT_EVENT,
474 BLUETOOTH_EVENT_OPC_DISCONNECTED,
477 __bt_free_sending_info(sending_info);
483 static void __bt_send_file_cb(GDBusProxy *proxy,
484 GAsyncResult *res, gpointer user_data)
487 GVariant *value = NULL;
488 GError *error = NULL;
489 char *session_path = NULL;
490 const char *transfer_name = NULL;
491 const char *file_name = NULL;
493 GVariantIter *iter = NULL;
494 value = g_dbus_proxy_call_finish(proxy, res, &error);
496 g_dbus_error_strip_remote_error(error);
497 BT_ERR("%s", error->message);
498 /* If Obex is not able to open a file then continue with other if any */
499 if (g_strcmp0("Unable to open file", error->message) == 0) {
500 GVariant *param = NULL;
503 BT_ERR("Unable to open file [%s]", sending_info->file_name_array[file_offset]);
505 param = g_variant_new("(issti)", BLUETOOTH_ERROR_NOT_FOUND,
506 sending_info->address,
507 sending_info->file_name_array[file_offset],
509 sending_info->request_id);
510 _bt_send_event(BT_OPP_CLIENT_EVENT,
511 BLUETOOTH_EVENT_OPC_TRANSFER_STARTED,
514 param = g_variant_new("(issti)", BLUETOOTH_ERROR_NOT_FOUND,
515 sending_info->address,
516 sending_info->file_name_array[file_offset],
518 sending_info->request_id);
519 _bt_send_event(BT_OPP_CLIENT_EVENT,
520 BLUETOOTH_EVENT_OPC_TRANSFER_COMPLETE,
524 g_object_unref(proxy);
531 g_object_unref(proxy);
534 g_variant_get(value, "(oa{sv})", &session_path, &iter);
535 g_variant_unref(value);
538 __bt_free_transfer_info(sending_info->transfer_info);
540 sending_info->transfer_info = g_malloc0(sizeof(bt_transfer_info_t));
546 while (g_variant_iter_loop(iter, "{sv}", &key, &val)) {
547 if (g_strcmp0(key, "Name") == 0)
548 transfer_name = g_variant_dup_string(val, &len);
549 else if (g_strcmp0(key, "Filename") == 0)
550 file_name = g_variant_dup_string(val, &len);
551 else if (g_strcmp0(key, "Size") == 0)
552 size = g_variant_get_uint64(val);
554 g_variant_iter_free(iter);
557 sending_info->transfer_info->transfer_name = g_strdup(transfer_name);
558 sending_info->transfer_info->file_name = g_strdup(file_name);
559 sending_info->transfer_info->size = size;
560 sending_info->transfer_info->progress = 0;
561 sending_info->transfer_info->transfer_path = session_path;
562 sending_info->transfer_info->transfer_status = BT_TRANSFER_STATUS_QUEUED;
563 sending_info->result = BLUETOOTH_ERROR_NONE;
566 g_free((gchar *)transfer_name);
567 g_free((gchar *)file_name);
570 void _bt_sending_files(void)
575 GDBusConnection *g_conn;
576 GDBusProxy *client_proxy;
577 gchar *mime_type = NULL;
579 if (sending_info == NULL)
581 if (file_offset < sending_info->file_count) {
582 /* Get the session bus. */
583 g_conn = _bt_gdbus_get_session_gconn();
584 ret_if(g_conn == NULL);
586 client_proxy = g_dbus_proxy_new_sync(g_conn, G_DBUS_PROXY_FLAGS_NONE,
587 NULL, BT_OBEXD_DBUS_NAME,
588 sending_info->session_path,
589 BT_OBEX_OBJECT_PUSH_INTERFACE,
591 ret_if(client_proxy == NULL);
592 if (mime_type_get_mime_type(sending_info->file_name_array[file_offset], &mime_type) == MIME_TYPE_ERROR_NONE) {
593 BT_DBG("MLME type = %s", mime_type);
595 /* For IOPT compliance, change "text/x-iMelody" to "audio/imelody"
596 * because few devices(multimedia players) reject the OPP put for text objects
597 * since they support only multimedia files exchange */
598 if (!strcasecmp(mime_type, "text/x-iMelody")) {
599 strncpy(mime_type, "audio/imelody", BT_MIME_TYPE_MAX_LEN);
600 BT_DBG("over writing mime type to = %s", mime_type);
602 if (!strcasecmp(mime_type, "text/vcard")) {
603 strncpy(mime_type, "text/x-vcard", BT_MIME_TYPE_MAX_LEN);
604 BT_DBG("over writing mime type to = %s", mime_type);
608 BT_DBG("Calling SendFile");
609 g_dbus_proxy_call(client_proxy, "SendFile",
610 g_variant_new("(ss)", sending_info->file_name_array[file_offset],
612 G_DBUS_CALL_FLAGS_NONE,
614 (GAsyncReadyCallback)__bt_send_file_cb,
617 BT_ERR("Calling SendFile failed: [%s]\n", err->message);
625 __bt_sending_release();
632 static void __bt_create_session_cb(GDBusProxy *proxy,
633 GAsyncResult *res, gpointer user_data)
637 GError *error = NULL;
639 int result = BLUETOOTH_ERROR_NONE;
640 char *session_path = NULL;
641 GVariant *param = NULL;
643 value = g_dbus_proxy_call_finish(proxy, res, &error);
645 g_variant_get(value, "(o)", &session_path);
646 g_variant_unref(value);
650 BT_ERR("%s", error->message);
651 g_clear_error(&error);
653 result = BLUETOOTH_ERROR_INTERNAL;
655 BT_DBG("Session created");
656 if (sending_info != NULL)
657 sending_info->session_path = g_strdup(session_path);
659 g_free(session_path);
660 g_object_unref(proxy);
661 ret_if(sending_info == NULL);
663 sending_info->result = result;
664 param = g_variant_new("(isi)", result,
665 sending_info->address,
666 sending_info->request_id);
667 /* Send the event in only error none case */
668 _bt_send_event(BT_OPP_CLIENT_EVENT,
669 BLUETOOTH_EVENT_OPC_CONNECTED,
672 if (result != BLUETOOTH_ERROR_NONE) {
673 BT_ERR("Calling __bt_sending_release");
674 gboolean ret = __bt_sending_release();
676 __bt_free_sending_info(sending_info);
680 BT_DBG("ReleaseSession Not called");
681 /* Operate remain works */
682 if (g_slist_length(transfer_list) > 0) {
683 bt_sending_data_t *data = NULL;
685 data = transfer_list->data;
686 ret_if(data == NULL);
688 transfer_list = g_slist_remove(transfer_list, data);
690 BT_DBG("calling __bt_opp_client_start_sending");
692 if (__bt_opp_client_start_sending(data->request_id,
693 data->address, data->file_path,
694 data->file_count) != BLUETOOTH_ERROR_NONE) {
695 BT_ERR("Sending Enqueued Transfer Failed");
700 BT_DBG("Calling sending_files");
707 static int __bt_opp_client_start_sending(int request_id, char *address,
708 char **file_name_array, int file_count)
710 GVariantBuilder *builder;
712 GDBusConnection *g_conn;
713 GDBusProxy *client_proxy;
714 GError *error = NULL;
717 BT_CHECK_PARAMETER(address, return);
718 BT_CHECK_PARAMETER(file_name_array, return);
720 /* Get the session bus. */
721 g_conn = _bt_gdbus_get_session_gconn();
722 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
724 client_proxy = g_dbus_proxy_new_sync(g_conn, G_DBUS_PROXY_FLAGS_NONE,
725 NULL, BT_OBEX_SERVICE_NAME,
727 BT_OBEX_CLIENT_INTERFACE,
731 BT_ERR("Unable to create client proxy: %s", error->message);
732 g_clear_error(&error);
735 retv_if(client_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
737 builder = g_variant_builder_new(
738 G_VARIANT_TYPE("a{sv}"));
740 g_variant_builder_add(builder, "{sv}", "Target",
741 g_variant_new_string("OPP"));
743 __bt_free_sending_info(sending_info);
745 sending_info = g_malloc0(sizeof(bt_sending_info_t));
746 sending_info->address = g_strdup(address);
747 sending_info->request_id = request_id;
749 sending_info->file_count = file_count;
750 sending_info->file_offset = 0;
751 sending_info->file_name_array = g_new0(char *, file_count + 1);
753 for (i = 0; i < file_count; i++) {
754 sending_info->file_name_array[i] = g_strdup(file_name_array[i]);
755 BT_DBG("file[%d]: %s", i, sending_info->file_name_array[i]);
758 _bt_opp_client_event_deinit();
759 _bt_opp_client_event_init();
760 //_bt_obex_client_started(agent_path);
762 BT_DBG("Adapter Status %d", _bt_adapter_get_status());
763 if (_bt_adapter_get_status() == BT_ACTIVATED) {
764 BT_DBG("Going to call CreateSession");
765 g_dbus_proxy_call(client_proxy, "CreateSession",
766 g_variant_new("(sa{sv})", address, builder),
767 G_DBUS_CALL_FLAGS_NONE,
769 (GAsyncReadyCallback)__bt_create_session_cb,
772 GVariant *param = g_variant_new("(isi)", BLUETOOTH_ERROR_INTERNAL,
773 sending_info->address, sending_info->request_id);
775 BT_DBG("Address[%s] RequestID[%d]", sending_info->address, sending_info->request_id);
776 _bt_send_event(BT_OPP_CLIENT_EVENT, BLUETOOTH_EVENT_OPC_CONNECTED,
778 __bt_free_sending_info(sending_info);
781 g_variant_builder_unref(builder);
785 return BLUETOOTH_ERROR_NONE;
788 int _bt_opp_client_push_files(int request_id, GDBusMethodInvocation *context,
789 bluetooth_device_address_t *remote_address,
790 char **file_path, int file_count)
793 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
794 bt_sending_data_t *data;
796 GVariant *out_param1 = NULL;
798 int result = BLUETOOTH_ERROR_NONE;
801 BT_CHECK_PARAMETER(remote_address, return);
802 BT_CHECK_PARAMETER(file_path, return);
804 /* Implement the queue */
805 _bt_convert_addr_type_to_string(address, remote_address->addr);
807 if (sending_info == NULL) {
808 result = __bt_opp_client_start_sending(request_id,
809 address, file_path, file_count);
810 if (result != BLUETOOTH_ERROR_NONE)
813 /* Insert data in the queue */
814 data = g_malloc0(sizeof(bt_sending_data_t));
815 data->file_path = g_new0(char *, file_count + 1);
816 data->address = g_strdup(address);
817 data->file_count = file_count;
818 data->request_id = request_id;
820 for (i = 0; i < file_count; i++) {
821 data->file_path[i] = g_strdup(file_path[i]);
822 DBG_SECURE("file[%d]: %s", i, data->file_path[i]);
825 transfer_list = g_slist_append(transfer_list, data);
828 out_param1 = g_variant_new_from_data((const GVariantType *)"ay",
829 &request_id, sizeof(int),
833 g_dbus_method_invocation_return_value(context,
834 g_variant_new("(iv)", result, out_param1));
841 int _bt_opp_client_cancel_push(void)
846 int result = BLUETOOTH_ERROR_CANCEL_BY_USER;
847 GVariant *ret = NULL;
848 GVariant *param = NULL;
849 retv_if(sending_info == NULL, BLUETOOTH_ERROR_NOT_IN_OPERATION);
851 sending_info->is_canceled = TRUE;
852 sending_info->result = result;
854 if (sending_info->transfer_info) {
856 ret = g_dbus_proxy_call_sync(sending_info->transfer_info->proxy,
858 G_DBUS_CALL_FLAGS_NONE, -1,
862 BT_ERR("Cancel Error: %s\n", err->message);
866 g_variant_unref(ret);
869 param = g_variant_new("(issti)", result,
870 sending_info->address,
871 sending_info->transfer_info->file_name,
872 sending_info->transfer_info->size,
873 sending_info->request_id);
874 _bt_send_event(BT_OPP_CLIENT_EVENT,
875 BLUETOOTH_EVENT_OPC_TRANSFER_COMPLETE,
878 if (result == BLUETOOTH_ERROR_CANCEL_BY_USER) {
879 BT_ERR("result is not BLUETOOTH_ERROR_NONE");
880 __bt_sending_release();
885 g_idle_add(__bt_cancel_push_cb, NULL);
890 return BLUETOOTH_ERROR_NONE;
893 int _bt_opp_client_cancel_all_transfers(void)
897 g_slist_free_full(transfer_list,
898 (GDestroyNotify)__bt_free_sending_data);
900 transfer_list = NULL;
903 _bt_opp_client_cancel_push();
905 return BLUETOOTH_ERROR_NONE;
908 int _bt_opp_client_is_sending(gboolean *sending)
910 BT_CHECK_PARAMETER(sending, return);
912 *sending = sending_info ? TRUE : FALSE;
914 return BLUETOOTH_ERROR_NONE;
917 void _bt_opp_client_check_pending_transfer(const char *address)
921 int result = BLUETOOTH_ERROR_CANCEL;
922 GVariant *param = NULL;
923 ret_if(sending_info == NULL);
924 ret_if(sending_info->transfer_info == NULL);
926 if (g_strcmp0(sending_info->address, address) == 0) {
927 BT_INFO("Address Match.Cancel current transfer");
928 sending_info->transfer_info->transfer_status = BT_TRANSFER_STATUS_COMPLETED;
929 sending_info->result = result;
931 if (!sending_info->is_canceled) {
932 param = g_variant_new("(issti)", result,
933 sending_info->address,
934 sending_info->transfer_info->file_name,
935 sending_info->transfer_info->size,
936 sending_info->request_id);
937 _bt_send_event(BT_OPP_CLIENT_EVENT,
938 BLUETOOTH_EVENT_OPC_TRANSFER_COMPLETE,
940 __bt_free_transfer_info(sending_info->transfer_info);
941 sending_info->transfer_info = NULL;
942 /* Reset the file offset as we will cancelled remaining files also */
945 param = g_variant_new("(isi)", sending_info->result,
946 sending_info->address,
947 sending_info->request_id);
948 _bt_send_event(BT_OPP_CLIENT_EVENT,
949 BLUETOOTH_EVENT_OPC_DISCONNECTED,
952 __bt_sending_release();
957 int _bt_opp_get_client_progress(guint8 *progress)
959 if (sending_info == NULL || sending_info->transfer_info == NULL) {
960 BT_ERR("No Active Outbound transfer");
961 return BLUETOOTH_ERROR_NOT_FOUND;
964 *progress = (int)(((double)sending_info->transfer_info->progress /
965 sending_info->transfer_info->size) * 100);
967 BT_DBG("Percentage: %d", *progress);
968 return BLUETOOTH_ERROR_NONE;
971 void _bt_cancel_queued_transfers(void)
973 bt_sending_data_t *data = NULL;
974 GVariant *param = NULL;
976 BT_INFO("Cancel queued Transfers:: Length of transfer list is %d",
977 g_slist_length(transfer_list));
979 while (transfer_list) {
980 data = transfer_list->data;
981 param = g_variant_new("(isi)", BLUETOOTH_ERROR_INTERNAL,
982 data->address, data->request_id);
984 BT_DBG("Address[%s] RequestID[%d]", data->address, data->request_id);
985 _bt_send_event(BT_OPP_CLIENT_EVENT, BLUETOOTH_EVENT_OPC_CONNECTED,
988 transfer_list = g_slist_remove(transfer_list, data);