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>
26 #include "bluetooth-api.h"
27 #include "bt-internal-types.h"
29 #include "bt-service-common.h"
30 #include "bt-service-event.h"
31 #include "bt-service-util.h"
32 #include "bt-service-opp-client.h"
33 #include "bt-service-obex-agent.h"
34 #include "bt-service-adapter.h"
36 #define BT_MIME_TYPE_MAX_LEN 20
38 static GSList *transfer_list = NULL;
39 bt_sending_info_t *sending_info;
40 static int file_offset = 0;
42 #define DBUS_TIEMOUT 20 * 1000 /* 20 Seconds */
43 static gboolean __bt_sending_release();
44 static int _bt_remove_session();
46 static int __bt_opp_client_start_sending(int request_id, char *address,
47 char **file_name_array, int file_count);
49 static GQuark __bt_opc_error_quark(void)
51 static GQuark quark = 0;
53 quark = g_quark_from_static_string("agent");
58 static void __bt_free_transfer_info(bt_transfer_info_t *info)
63 g_object_unref(info->proxy);
65 if (info->properties_proxy)
66 g_object_unref(info->properties_proxy);
69 g_free(info->transfer_name);
70 g_free(info->file_name);
74 static void __bt_free_sending_info(bt_sending_info_t *info)
78 /* Free the sending variable */
79 __bt_free_transfer_info(info->transfer_info);
81 g_free(info->file_name_array);
83 g_free(info->address);
87 static gboolean __bt_cancel_push_cb(gpointer data)
91 int result = BLUETOOTH_ERROR_CANCEL_BY_USER;
92 GVariant *param = NULL;
93 retv_if(sending_info == NULL, FALSE);
94 sending_info->result = result;
96 param = g_variant_new("(isi)", result,
97 sending_info->address,
98 sending_info->request_id);
99 /* Send the event in only error none case */
100 _bt_send_event(BT_OPP_CLIENT_EVENT,
101 BLUETOOTH_EVENT_OPC_CONNECTED,
103 __bt_free_sending_info(sending_info);
106 _bt_opp_client_event_deinit();
108 BT_DBG("Length of transfer list is %d", g_slist_length(transfer_list));
110 /*Operate remain works*/
111 if (g_slist_length(transfer_list) > 0) {
112 bt_sending_data_t *node = NULL;
114 node = transfer_list->data;
116 BT_ERR("data is NULL");
120 transfer_list = g_slist_remove(transfer_list, node);
122 if (__bt_opp_client_start_sending(node->request_id,
123 node->address, node->file_path,
124 node->file_count) != BLUETOOTH_ERROR_NONE) {
125 BT_ERR("Fail to start sending");
132 gboolean _bt_obex_client_progress(const char *transfer_path, guint64 transferred)
136 int percentage_progress;
137 int previous_progress;
139 int result = BLUETOOTH_ERROR_NONE;
140 GVariant *param = NULL;
141 retv_if(sending_info == NULL, TRUE);
142 retv_if(sending_info->transfer_info == NULL, TRUE);
144 if (g_strcmp0(sending_info->transfer_info->transfer_path,
145 transfer_path) != 0) {
146 BT_INFO("Path mismatch, previous transfer failed! Returning");
150 size = sending_info->transfer_info->size;
152 percentage_progress = (int)(((gdouble)transferred /(gdouble)size) * 100);
154 percentage_progress = 0;
156 sending_info->transfer_info->transfer_status = BT_TRANSFER_STATUS_PROGRESS;
157 sending_info->result = result;
159 previous_progress = (int)(((gdouble)sending_info->transfer_info->progress /(gdouble)size) * 100);
160 if (percentage_progress == previous_progress &&
161 sending_info->transfer_info->progress) {
162 sending_info->transfer_info->progress = transferred;
165 BT_DBG("Sending progress [prev %d] [curr %d]",
166 previous_progress, percentage_progress);
168 sending_info->transfer_info->progress = transferred;
170 /* Send the event in only error none case */
171 param = g_variant_new("(istii)", result,
172 sending_info->transfer_info->file_name,
173 sending_info->transfer_info->size,
175 sending_info->request_id);
178 _bt_send_event(BT_OPP_CLIENT_EVENT,
179 BLUETOOTH_EVENT_OPC_TRANSFER_PROGRESS,
186 gboolean _bt_obex_client_completed(const char *transfer_path, gboolean success)
190 int result = BLUETOOTH_ERROR_NONE;
191 GVariant *param = NULL;
192 retv_if(sending_info == NULL, TRUE);
193 retv_if(sending_info->transfer_info == NULL, TRUE);
195 if (g_strcmp0(sending_info->transfer_info->transfer_path,
196 transfer_path) != 0) {
197 BT_INFO("Path mismatch, previous transfer failed! Returning");
201 result = (success == TRUE) ? BLUETOOTH_ERROR_NONE : BLUETOOTH_ERROR_CANCEL;
203 sending_info->transfer_info->transfer_status = BT_TRANSFER_STATUS_COMPLETED;
204 sending_info->result = result;
206 if (!success) { /*In case of remote device reject, we need to send BLUETOOTH_EVENT_OPC_DISCONNECTED */
207 BT_DBG("completed with error");
208 if (!sending_info->is_canceled) {
209 param = g_variant_new("(issti)", result,
210 sending_info->address,
211 sending_info->transfer_info->file_name,
212 sending_info->transfer_info->size,
213 sending_info->request_id);
214 _bt_send_event(BT_OPP_CLIENT_EVENT,
215 BLUETOOTH_EVENT_OPC_TRANSFER_COMPLETE,
217 __bt_free_transfer_info(sending_info->transfer_info);
218 sending_info->transfer_info = NULL;
219 /* Reset the file offset as we will cancelled remaining files also */
222 param = g_variant_new("(isi)", sending_info->result,
223 sending_info->address,
224 sending_info->request_id);
225 _bt_send_event(BT_OPP_CLIENT_EVENT,
226 BLUETOOTH_EVENT_OPC_DISCONNECTED,
228 __bt_sending_release();
229 /* Sending info should not freed after sending_release it's
230 * already freed in that API and if any pending request is
231 * present then it recreate sending_info again.
232 * And if we free it here then CreateSession method call will
233 * made but RemoveSession method call will not done.
236 BT_DBG("complete success");
237 /* Send the event in only error none case */
238 param = g_variant_new("(issti)", result,
239 sending_info->address,
240 sending_info->transfer_info->file_name,
241 sending_info->transfer_info->size,
242 sending_info->request_id);
243 _bt_send_event(BT_OPP_CLIENT_EVENT,
244 BLUETOOTH_EVENT_OPC_TRANSFER_COMPLETE,
246 __bt_free_transfer_info(sending_info->transfer_info);
247 sending_info->transfer_info = NULL;
255 gboolean _bt_obex_client_started(const char *transfer_path)
259 int result = BLUETOOTH_ERROR_NONE;
260 GError *error = NULL;
261 GVariant *param = NULL;
262 GDBusConnection *g_conn;
263 GDBusProxy *properties_proxy;
264 GDBusProxy *transfer_proxy;
266 if (sending_info == NULL || sending_info->is_canceled == TRUE) {
267 result = BLUETOOTH_ERROR_CANCEL_BY_USER;
271 /* Get the session bus. */
272 g_conn = _bt_get_session_gconn();
273 retv_if(g_conn == NULL, FALSE);
274 properties_proxy = g_dbus_proxy_new_sync(g_conn, G_DBUS_PROXY_FLAGS_NONE,
275 NULL, BT_OBEXD_DBUS_NAME,
276 transfer_path, BT_PROPERTIES_INTERFACE,
279 retv_if(properties_proxy == NULL, FALSE);
281 sending_info->transfer_info->properties_proxy = properties_proxy;
283 transfer_proxy = g_dbus_proxy_new_sync(g_conn, G_DBUS_PROXY_FLAGS_NONE,
284 NULL, BT_OBEXD_DBUS_NAME,
285 transfer_path, BT_OBEX_TRANSFER_INTERFACE,
288 retv_if(transfer_proxy == NULL, FALSE);
290 sending_info->transfer_info->proxy = transfer_proxy;
292 sending_info->transfer_info->transfer_status = BT_TRANSFER_STATUS_STARTED;
293 sending_info->result = result;
295 param = g_variant_new("(issti)", result,
296 sending_info->address,
297 sending_info->transfer_info->file_name,
298 sending_info->transfer_info->size,
299 sending_info->request_id);
300 _bt_send_event(BT_OPP_CLIENT_EVENT,
301 BLUETOOTH_EVENT_OPC_TRANSFER_STARTED,
307 error = g_error_new(__bt_opc_error_quark(), BT_OBEX_AGENT_ERROR_CANCEL,
316 static void __bt_free_sending_data(gpointer data)
319 bt_sending_data_t *info = data;
321 ret_if(info == NULL);
323 for (i = 0; i < info->file_count; i++) {
324 g_free(info->file_path[i]);
327 _bt_delete_request_id(info->request_id);
329 g_free(info->file_path);
330 g_free(info->address);
334 static void __bt_sending_release_cb(GDBusProxy *proxy,
335 GAsyncResult *res, gpointer user_data)
338 ret_if(sending_info == NULL);
340 GError *error = NULL;
341 int result = BLUETOOTH_ERROR_NONE;
342 GVariant *param = NULL;
343 g_dbus_proxy_call_finish(proxy, res, &error);
345 g_object_unref(proxy);
348 BT_ERR("%s", error->message);
351 result = BLUETOOTH_ERROR_INTERNAL;
354 BT_DBG("Session Removed");
357 sending_info->result = result;
358 param = g_variant_new("(isi)", sending_info->result,
359 sending_info->address,
360 sending_info->request_id);
361 /* Send the event in only error none case */
362 _bt_send_event(BT_OPP_CLIENT_EVENT,
363 BLUETOOTH_EVENT_OPC_DISCONNECTED,
366 __bt_free_sending_info(sending_info);
369 _bt_opp_client_event_deinit();
371 /* Operate remain works */
372 if (g_slist_length(transfer_list) > 0) {
373 bt_sending_data_t *data = NULL;
375 data = transfer_list->data;
379 transfer_list = g_slist_remove(transfer_list, data);
381 BT_DBG("calling __bt_opp_client_start_sending");
383 if (__bt_opp_client_start_sending(data->request_id,
384 data->address, data->file_path,
385 data->file_count) != BLUETOOTH_ERROR_NONE) {
392 g_slist_free_full(transfer_list,
393 (GDestroyNotify)__bt_free_sending_data);
394 transfer_list = NULL;
401 static int _bt_remove_session()
403 GDBusConnection *g_conn;
404 GDBusProxy *session_proxy;
407 g_conn = _bt_get_session_gconn();
408 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
409 retv_if(sending_info->session_path == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
411 session_proxy = g_dbus_proxy_new_sync(g_conn, G_DBUS_PROXY_FLAGS_NONE,
412 NULL, BT_OBEXD_DBUS_NAME,
414 BT_OBEX_CLIENT_INTERFACE,
417 retv_if(session_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
419 g_dbus_proxy_call(session_proxy, "RemoveSession",
420 g_variant_new("(o)", sending_info->session_path),
421 G_DBUS_CALL_FLAGS_NONE,
423 (GAsyncReadyCallback)__bt_sending_release_cb,
426 return BLUETOOTH_ERROR_NONE;
429 static gboolean __bt_sending_release()
433 retv_if(sending_info == NULL, FALSE);
435 retv_if(_bt_remove_session() != BLUETOOTH_ERROR_NONE, FALSE);
441 void _bt_opc_disconnected(const char *session_path)
444 GVariant *param = NULL;
445 ret_if(sending_info == NULL);
447 if (g_strcmp0(sending_info->session_path,
448 session_path) != 0) {
449 BT_INFO("Path mismatch, previous transfer failed! Returning");
453 if (sending_info->transfer_info) {
454 if (sending_info->transfer_info->transfer_status == BT_TRANSFER_STATUS_PROGRESS ||
455 sending_info->transfer_info->transfer_status == BT_TRANSFER_STATUS_STARTED) {
456 BT_INFO("Abnormal termination");
457 param = g_variant_new("(issti)", sending_info->result,
458 sending_info->address,
459 sending_info->transfer_info->file_name,
460 sending_info->transfer_info->size,
461 sending_info->request_id);
462 _bt_send_event(BT_OPP_CLIENT_EVENT,
463 BLUETOOTH_EVENT_OPC_TRANSFER_COMPLETE,
465 __bt_free_transfer_info(sending_info->transfer_info);
468 param = g_variant_new("(isi)", sending_info->result,
469 sending_info->address,
470 sending_info->request_id);
471 _bt_send_event(BT_OPP_CLIENT_EVENT,
472 BLUETOOTH_EVENT_OPC_DISCONNECTED,
475 __bt_free_sending_info(sending_info);
481 static void __bt_send_file_cb(GDBusProxy *proxy,
482 GAsyncResult *res, gpointer user_data)
485 GVariant *value = NULL;
486 GError *error = NULL;
487 char *session_path = NULL;
488 const char *transfer_name = NULL;
489 const char *file_name = NULL;
491 GVariantIter *iter = NULL;
492 value = g_dbus_proxy_call_finish(proxy, res, &error);
494 g_dbus_error_strip_remote_error(error);
495 BT_ERR("%s", error->message);
496 /* If Obex is not able to open a file then continue with other if any */
497 if (g_strcmp0("Unable to open file", error->message) == 0) {
498 GVariant *param = NULL;
501 BT_ERR("Unable to open file [%s]", sending_info->file_name_array[file_offset]);
503 param = g_variant_new("(issti)", BLUETOOTH_ERROR_NOT_FOUND,
504 sending_info->address,
505 sending_info->file_name_array[file_offset],
507 sending_info->request_id);
508 _bt_send_event(BT_OPP_CLIENT_EVENT,
509 BLUETOOTH_EVENT_OPC_TRANSFER_STARTED,
512 param = g_variant_new("(issti)", BLUETOOTH_ERROR_NOT_FOUND,
513 sending_info->address,
514 sending_info->file_name_array[file_offset],
516 sending_info->request_id);
517 _bt_send_event(BT_OPP_CLIENT_EVENT,
518 BLUETOOTH_EVENT_OPC_TRANSFER_COMPLETE,
522 g_object_unref(proxy);
529 g_object_unref(proxy);
532 g_variant_get(value, "(oa{sv})", &session_path, &iter);
533 g_variant_unref(value);
536 __bt_free_transfer_info(sending_info->transfer_info);
538 sending_info->transfer_info = g_malloc0(sizeof(bt_transfer_info_t));
544 while (g_variant_iter_loop(iter, "{sv}", &key, &val)) {
545 if (g_strcmp0(key, "Name") == 0) {
546 transfer_name = g_variant_dup_string(val, &len);
547 } else if (g_strcmp0(key, "Filename") == 0) {
548 file_name = g_variant_dup_string(val, &len);
549 } else if (g_strcmp0(key, "Size") == 0) {
550 size = g_variant_get_uint64(val);
553 g_variant_iter_free(iter);
556 sending_info->transfer_info->transfer_name = g_strdup(transfer_name);
557 sending_info->transfer_info->file_name = g_strdup(file_name);
558 sending_info->transfer_info->size = size;
559 sending_info->transfer_info->progress = 0;
560 sending_info->transfer_info->transfer_path = session_path;
561 sending_info->transfer_info->transfer_status = BT_TRANSFER_STATUS_QUEUED;
562 sending_info->result = BLUETOOTH_ERROR_NONE;
565 g_free((gchar *)transfer_name);
566 g_free((gchar *)file_name);
569 void _bt_sending_files(void)
574 GDBusConnection *g_conn;
575 GDBusProxy *client_proxy;
576 char mime_type[BT_MIME_TYPE_MAX_LEN + 1] = { 0 };
578 if (sending_info == NULL)
580 if (file_offset < sending_info->file_count) {
581 /* Get the session bus. */
582 g_conn = _bt_get_session_gconn();
583 ret_if(g_conn == NULL);
585 client_proxy = g_dbus_proxy_new_sync(g_conn, G_DBUS_PROXY_FLAGS_NONE,
586 NULL, BT_OBEXD_DBUS_NAME,
587 sending_info->session_path,
588 BT_OBEX_OBJECT_PUSH_INTERFACE,
590 ret_if(client_proxy == NULL);
591 if (aul_get_mime_from_file(sending_info->file_name_array[file_offset],
592 mime_type, BT_MIME_TYPE_MAX_LEN) == AUL_R_OK) {
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);
624 __bt_sending_release();
630 static void __bt_create_session_cb(GDBusProxy *proxy,
631 GAsyncResult *res, gpointer user_data)
635 GError *error = NULL;
637 int result = BLUETOOTH_ERROR_NONE;
638 char *session_path = NULL;
639 GVariant *param = NULL;
641 value = g_dbus_proxy_call_finish(proxy, res, &error);
643 g_variant_get(value, "(o)", &session_path);
644 g_variant_unref(value);
648 BT_ERR("%s", error->message);
649 g_clear_error(&error);
651 result = BLUETOOTH_ERROR_INTERNAL;
653 BT_DBG("Session created");
654 if (sending_info != NULL)
655 sending_info->session_path = g_strdup(session_path);
657 g_free(session_path);
658 g_object_unref(proxy);
659 ret_if(sending_info == NULL);
661 sending_info->result = result;
662 param = g_variant_new("(isi)", result,
663 sending_info->address,
664 sending_info->request_id);
665 /* Send the event in only error none case */
666 _bt_send_event(BT_OPP_CLIENT_EVENT,
667 BLUETOOTH_EVENT_OPC_CONNECTED,
670 if (result != BLUETOOTH_ERROR_NONE) {
671 BT_ERR("Calling __bt_sending_release");
672 gboolean ret = __bt_sending_release();
674 __bt_free_sending_info(sending_info);
678 BT_DBG("ReleaseSession Not called");
679 /* Operate remain works */
680 if (g_slist_length(transfer_list) > 0) {
681 bt_sending_data_t *data = NULL;
683 data = transfer_list->data;
684 ret_if(data == NULL);
686 transfer_list = g_slist_remove(transfer_list, data);
688 BT_DBG("calling __bt_opp_client_start_sending");
690 if (__bt_opp_client_start_sending(data->request_id,
691 data->address, data->file_path,
692 data->file_count) != BLUETOOTH_ERROR_NONE) {
693 BT_ERR("Sending Enqueued Transfer Failed");
698 BT_DBG("Calling sending_files");
705 static int __bt_opp_client_start_sending(int request_id, char *address,
706 char **file_name_array, int file_count)
708 GVariantBuilder *builder;
710 GDBusConnection *g_conn;
711 GDBusProxy *client_proxy;
712 GError *error = NULL;
715 BT_CHECK_PARAMETER(address, return);
716 BT_CHECK_PARAMETER(file_name_array, return);
718 /* Get the session bus. */
719 g_conn = _bt_get_session_gconn();
720 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
722 client_proxy = g_dbus_proxy_new_sync(g_conn, G_DBUS_PROXY_FLAGS_NONE,
723 NULL, BT_OBEX_SERVICE_NAME,
725 BT_OBEX_CLIENT_INTERFACE,
729 BT_ERR("Unable to create client proxy: %s", error->message);
730 g_clear_error(&error);
733 retv_if(client_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
735 builder = g_variant_builder_new(
736 G_VARIANT_TYPE("a{sv}"));
738 g_variant_builder_add(builder, "{sv}", "Target",
739 g_variant_new_string("OPP"));
741 __bt_free_sending_info(sending_info);
743 sending_info = g_malloc0(sizeof(bt_sending_info_t));
744 sending_info->address = g_strdup(address);
745 sending_info->request_id = request_id;
747 sending_info->file_count = file_count;
748 sending_info->file_offset = 0;
749 sending_info->file_name_array = g_new0(char *, file_count + 1);
751 for (i = 0; i < file_count; i++) {
752 sending_info->file_name_array[i] = g_strdup(file_name_array[i]);
753 BT_DBG("file[%d]: %s", i, sending_info->file_name_array[i]);
756 _bt_opp_client_event_deinit();
757 _bt_opp_client_event_init();
758 //_bt_obex_client_started(agent_path);
760 BT_DBG("Adapter Status %d", _bt_adapter_get_status());
761 if (_bt_adapter_get_status() == BT_ACTIVATED) {
762 BT_DBG("Going to call CreateSession");
763 g_dbus_proxy_call(client_proxy, "CreateSession",
764 g_variant_new("(sa{sv})", address, builder),
765 G_DBUS_CALL_FLAGS_NONE,
767 (GAsyncReadyCallback)__bt_create_session_cb,
770 GVariant *param = g_variant_new("(isi)", BLUETOOTH_ERROR_INTERNAL,
771 sending_info->address, sending_info->request_id);
773 BT_DBG("Address[%s] RequestID[%d]", sending_info->address, sending_info->request_id);
774 _bt_send_event(BT_OPP_CLIENT_EVENT, BLUETOOTH_EVENT_OPC_CONNECTED,
776 __bt_free_sending_info(sending_info);
779 g_variant_builder_unref(builder);
783 return BLUETOOTH_ERROR_NONE;
786 int _bt_opp_client_push_files(int request_id, GDBusMethodInvocation *context,
787 bluetooth_device_address_t *remote_address,
788 char **file_path, int file_count)
791 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
792 bt_sending_data_t *data;
794 GVariant *out_param1 = NULL;
796 int result = BLUETOOTH_ERROR_NONE;
799 BT_CHECK_PARAMETER(remote_address, return);
800 BT_CHECK_PARAMETER(file_path, return);
802 /* Implement the queue */
803 _bt_convert_addr_type_to_string(address, remote_address->addr);
805 if (sending_info == NULL) {
806 result = __bt_opp_client_start_sending(request_id,
807 address, file_path, file_count);
808 if (result != BLUETOOTH_ERROR_NONE)
811 /* Insert data in the queue */
812 data = g_malloc0(sizeof(bt_sending_data_t));
814 return BLUETOOTH_ERROR_MEMORY_ALLOCATION;
816 data->file_path = g_new0(char *, file_count + 1);
817 data->address = g_strdup(address);
818 data->file_count = file_count;
819 data->request_id = request_id;
821 for (i = 0; i < file_count; i++) {
822 data->file_path[i] = g_strdup(file_path[i]);
823 DBG_SECURE("file[%d]: %s", i, data->file_path[i]);
826 transfer_list = g_slist_append(transfer_list, data);
829 out_param1 = g_variant_new_from_data((const GVariantType *)"ay",
830 &request_id, sizeof(int),
834 g_dbus_method_invocation_return_value(context,
835 g_variant_new("(iv)", result, out_param1));
842 int _bt_opp_client_cancel_push(void)
847 int result = BLUETOOTH_ERROR_CANCEL_BY_USER;
848 GVariant *ret = NULL;
849 GVariant *param = NULL;
850 retv_if(sending_info == NULL, BLUETOOTH_ERROR_NOT_IN_OPERATION);
852 sending_info->is_canceled = TRUE;
853 sending_info->result = result;
855 if (sending_info->transfer_info) {
857 ret = g_dbus_proxy_call_sync(sending_info->transfer_info->proxy,
859 G_DBUS_CALL_FLAGS_NONE, -1,
863 BT_ERR("Cancel Error: %s\n", err->message);
867 g_variant_unref(ret);
870 param = g_variant_new("(issti)", result,
871 sending_info->address,
872 sending_info->transfer_info->file_name,
873 sending_info->transfer_info->size,
874 sending_info->request_id);
875 _bt_send_event(BT_OPP_CLIENT_EVENT,
876 BLUETOOTH_EVENT_OPC_TRANSFER_COMPLETE,
879 if (result == BLUETOOTH_ERROR_CANCEL_BY_USER) {
880 BT_ERR("result is not BLUETOOTH_ERROR_NONE");
881 __bt_sending_release();
886 g_idle_add(__bt_cancel_push_cb, NULL);
891 return BLUETOOTH_ERROR_NONE;
894 int _bt_opp_client_cancel_all_transfers(void)
898 g_slist_free_full(transfer_list,
899 (GDestroyNotify)__bt_free_sending_data);
901 transfer_list = NULL;
904 _bt_opp_client_cancel_push();
906 return BLUETOOTH_ERROR_NONE;
909 int _bt_opp_client_is_sending(gboolean *sending)
911 BT_CHECK_PARAMETER(sending, return);
913 *sending = sending_info ? TRUE : FALSE;
915 return BLUETOOTH_ERROR_NONE;
918 void _bt_opp_client_check_pending_transfer(const char *address)
922 int result = BLUETOOTH_ERROR_CANCEL;
923 GVariant *param = NULL;
924 ret_if(sending_info == NULL);
925 ret_if(sending_info->transfer_info == NULL);
927 if (g_strcmp0(sending_info->address, address) == 0) {
928 BT_INFO("Address Match.Cancel current transfer");
929 sending_info->transfer_info->transfer_status = BT_TRANSFER_STATUS_COMPLETED;
930 sending_info->result = result;
932 if (!sending_info->is_canceled) {
933 param = g_variant_new("(issti)", result,
934 sending_info->address,
935 sending_info->transfer_info->file_name,
936 sending_info->transfer_info->size,
937 sending_info->request_id);
938 _bt_send_event(BT_OPP_CLIENT_EVENT,
939 BLUETOOTH_EVENT_OPC_TRANSFER_COMPLETE,
941 __bt_free_transfer_info(sending_info->transfer_info);
942 sending_info->transfer_info = NULL;
943 /* Reset the file offset as we will cancelled remaining files also */
946 param = g_variant_new("(isi)", sending_info->result,
947 sending_info->address,
948 sending_info->request_id);
949 _bt_send_event(BT_OPP_CLIENT_EVENT,
950 BLUETOOTH_EVENT_OPC_DISCONNECTED,
953 __bt_sending_release();
958 int _bt_opp_get_client_progress(guint8 *progress)
960 if (sending_info == NULL || sending_info->transfer_info == NULL) {
961 BT_ERR("No Active Outbound transfer");
962 return BLUETOOTH_ERROR_NOT_FOUND;
965 *progress = (int)(((double)sending_info->transfer_info->progress /
966 sending_info->transfer_info->size) * 100);
968 BT_DBG("Percentage: %d", *progress);
969 return BLUETOOTH_ERROR_NONE;
972 void _bt_cancel_queued_transfers(void)
974 bt_sending_data_t *data = NULL;
975 GVariant *param = NULL;
977 BT_INFO("Cancel queued Transfers:: Length of transfer list is %d",
978 g_slist_length(transfer_list));
980 while (transfer_list) {
981 data = transfer_list->data;
982 param = g_variant_new("(isi)", BLUETOOTH_ERROR_INTERNAL,
983 data->address, data->request_id);
985 BT_DBG("Address[%s] RequestID[%d]", data->address, data->request_id);
986 _bt_send_event(BT_OPP_CLIENT_EVENT, BLUETOOTH_EVENT_OPC_CONNECTED,
989 transfer_list = g_slist_remove(transfer_list, data);