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.
24 #include "bluetooth-api.h"
25 #include "bt-internal-types.h"
27 #include "bt-service-common.h"
28 #include "bt-service-event.h"
29 #include "bt-service-util.h"
30 #include "bt-service-opp-client.h"
31 #include "bt-service-obex-agent.h"
32 #include "bt-service-adapter.h"
34 #define BT_MIME_TYPE_MAX_LEN 20
36 static GSList *transfer_list = NULL;
37 bt_sending_info_t *sending_info;
38 static int file_offset = 0;
40 #define DBUS_TIEMOUT 20 * 1000 /* 20 Seconds */
41 static gboolean __bt_sending_release();
42 static int _bt_remove_session();
44 static int __bt_opp_client_start_sending(int request_id, char *address,
45 char **file_name_array, int file_count);
47 static GQuark __bt_opc_error_quark(void)
49 static GQuark quark = 0;
51 quark = g_quark_from_static_string("agent");
56 static void __bt_free_transfer_info(bt_transfer_info_t *info)
61 g_object_unref(info->proxy);
63 if (info->properties_proxy)
64 g_object_unref(info->properties_proxy);
67 g_free(info->transfer_name);
68 g_free(info->file_name);
72 static void __bt_free_sending_info(bt_sending_info_t *info)
76 /* Free the sending variable */
77 __bt_free_transfer_info(info->transfer_info);
79 g_free(info->file_name_array);
81 g_free(info->address);
85 static gboolean __bt_cancel_push_cb(gpointer data)
89 int result = BLUETOOTH_ERROR_CANCEL_BY_USER;
90 GVariant *param = NULL;
91 retv_if(sending_info == NULL, FALSE);
92 sending_info->result = result;
94 param = g_variant_new("(isi)", result,
95 sending_info->address,
96 sending_info->request_id);
97 /* Send the event in only error none case */
98 _bt_send_event(BT_OPP_CLIENT_EVENT,
99 BLUETOOTH_EVENT_OPC_CONNECTED,
101 __bt_free_sending_info(sending_info);
104 _bt_opp_client_event_deinit();
106 BT_DBG("Length of transfer list is %d", g_slist_length(transfer_list));
108 /*Operate remain works*/
109 if (g_slist_length(transfer_list) > 0) {
110 bt_sending_data_t *node = NULL;
112 node = transfer_list->data;
114 BT_ERR("data is NULL");
118 transfer_list = g_slist_remove(transfer_list, node);
120 if (__bt_opp_client_start_sending(node->request_id,
121 node->address, node->file_path,
122 node->file_count) != BLUETOOTH_ERROR_NONE) {
123 BT_ERR("Fail to start sending");
130 gboolean _bt_obex_client_progress(const char *transfer_path, guint64 transferred)
134 int percentage_progress;
135 int previous_progress;
137 int result = BLUETOOTH_ERROR_NONE;
138 GVariant *param = NULL;
139 retv_if(sending_info == NULL, TRUE);
140 retv_if(sending_info->transfer_info == NULL, TRUE);
142 if (g_strcmp0(sending_info->transfer_info->transfer_path,
143 transfer_path) != 0) {
144 BT_INFO("Path mismatch, previous transfer failed! Returning");
148 size = sending_info->transfer_info->size;
150 percentage_progress = (int)(((gdouble)transferred /(gdouble)size) * 100);
152 percentage_progress = 0;
154 sending_info->transfer_info->transfer_status = BT_TRANSFER_STATUS_PROGRESS;
155 sending_info->result = result;
157 previous_progress = (int)(((gdouble)sending_info->transfer_info->progress /(gdouble)size) * 100);
158 if (percentage_progress == previous_progress &&
159 sending_info->transfer_info->progress) {
160 sending_info->transfer_info->progress = transferred;
163 BT_DBG("Sending progress [prev %d] [curr %d]",
164 previous_progress, percentage_progress);
166 sending_info->transfer_info->progress = transferred;
168 /* Send the event in only error none case */
169 param = g_variant_new("(istii)", result,
170 sending_info->transfer_info->file_name,
171 sending_info->transfer_info->size,
173 sending_info->request_id);
176 _bt_send_event(BT_OPP_CLIENT_EVENT,
177 BLUETOOTH_EVENT_OPC_TRANSFER_PROGRESS,
184 gboolean _bt_obex_client_completed(const char *transfer_path, gboolean success)
188 int result = BLUETOOTH_ERROR_NONE;
189 GVariant *param = NULL;
190 retv_if(sending_info == NULL, TRUE);
191 retv_if(sending_info->transfer_info == NULL, TRUE);
193 if (g_strcmp0(sending_info->transfer_info->transfer_path,
194 transfer_path) != 0) {
195 BT_INFO("Path mismatch, previous transfer failed! Returning");
199 result = (success == TRUE) ? BLUETOOTH_ERROR_NONE : BLUETOOTH_ERROR_CANCEL;
201 sending_info->transfer_info->transfer_status = BT_TRANSFER_STATUS_COMPLETED;
202 sending_info->result = result;
204 if (!success) { /*In case of remote device reject, we need to send BLUETOOTH_EVENT_OPC_DISCONNECTED */
205 BT_DBG("completed with error");
206 if (!sending_info->is_canceled) {
207 param = g_variant_new("(issti)", result,
208 sending_info->address,
209 sending_info->transfer_info->file_name,
210 sending_info->transfer_info->size,
211 sending_info->request_id);
212 _bt_send_event(BT_OPP_CLIENT_EVENT,
213 BLUETOOTH_EVENT_OPC_TRANSFER_COMPLETE,
215 __bt_free_transfer_info(sending_info->transfer_info);
216 sending_info->transfer_info = NULL;
217 /* Reset the file offset as we will cancelled remaining files also */
220 param = g_variant_new("(isi)", sending_info->result,
221 sending_info->address,
222 sending_info->request_id);
223 _bt_send_event(BT_OPP_CLIENT_EVENT,
224 BLUETOOTH_EVENT_OPC_DISCONNECTED,
226 __bt_sending_release();
227 /* Sending info should not freed after sending_release it's
228 * already freed in that API and if any pending request is
229 * present then it recreate sending_info again.
230 * And if we free it here then CreateSession method call will
231 * made but RemoveSession method call will not done.
234 BT_DBG("complete success");
235 /* Send the event in only error none case */
236 param = g_variant_new("(issti)", result,
237 sending_info->address,
238 sending_info->transfer_info->file_name,
239 sending_info->transfer_info->size,
240 sending_info->request_id);
241 _bt_send_event(BT_OPP_CLIENT_EVENT,
242 BLUETOOTH_EVENT_OPC_TRANSFER_COMPLETE,
244 __bt_free_transfer_info(sending_info->transfer_info);
245 sending_info->transfer_info = NULL;
253 gboolean _bt_obex_client_started(const char *transfer_path)
257 int result = BLUETOOTH_ERROR_NONE;
258 GError *error = NULL;
259 GVariant *param = NULL;
260 GDBusConnection *g_conn;
261 GDBusProxy *properties_proxy;
262 GDBusProxy *transfer_proxy;
264 if (sending_info == NULL || sending_info->is_canceled == TRUE) {
265 result = BLUETOOTH_ERROR_CANCEL_BY_USER;
269 /* Get the session bus. */
270 g_conn = _bt_gdbus_get_system_gconn();
271 retv_if(g_conn == NULL, FALSE);
272 properties_proxy = g_dbus_proxy_new_sync(g_conn, G_DBUS_PROXY_FLAGS_NONE,
273 NULL, BT_OBEXD_DBUS_NAME,
274 transfer_path, BT_PROPERTIES_INTERFACE,
277 retv_if(properties_proxy == NULL, FALSE);
279 sending_info->transfer_info->properties_proxy = properties_proxy;
281 transfer_proxy = g_dbus_proxy_new_sync(g_conn, G_DBUS_PROXY_FLAGS_NONE,
282 NULL, BT_OBEXD_DBUS_NAME,
283 transfer_path, BT_OBEX_TRANSFER_INTERFACE,
286 retv_if(transfer_proxy == NULL, FALSE);
288 sending_info->transfer_info->proxy = transfer_proxy;
290 sending_info->transfer_info->transfer_status = BT_TRANSFER_STATUS_STARTED;
291 sending_info->result = result;
293 param = g_variant_new("(issti)", result,
294 sending_info->address,
295 sending_info->transfer_info->file_name,
296 sending_info->transfer_info->size,
297 sending_info->request_id);
298 _bt_send_event(BT_OPP_CLIENT_EVENT,
299 BLUETOOTH_EVENT_OPC_TRANSFER_STARTED,
305 error = g_error_new(__bt_opc_error_quark(), BT_OBEX_AGENT_ERROR_CANCEL,
314 static void __bt_free_sending_data(gpointer data)
317 bt_sending_data_t *info = data;
319 ret_if(info == NULL);
321 for (i = 0; i < info->file_count; i++)
322 g_free(info->file_path[i]);
324 _bt_delete_request_id(info->request_id);
326 g_free(info->file_path);
327 g_free(info->address);
331 static void __bt_sending_release_cb(GDBusProxy *proxy,
332 GAsyncResult *res, gpointer user_data)
335 ret_if(sending_info == NULL);
337 GError *error = NULL;
338 int result = BLUETOOTH_ERROR_NONE;
339 GVariant *param = NULL;
340 GVariant *reply = NULL;
342 reply = g_dbus_proxy_call_finish(proxy, res, &error);
344 g_object_unref(proxy);
346 g_variant_unref(reply);
349 BT_ERR("%s", error->message);
352 result = BLUETOOTH_ERROR_INTERNAL;
355 BT_DBG("Session Removed");
358 sending_info->result = result;
359 param = g_variant_new("(isi)", sending_info->result,
360 sending_info->address,
361 sending_info->request_id);
362 /* Send the event in only error none case */
363 _bt_send_event(BT_OPP_CLIENT_EVENT,
364 BLUETOOTH_EVENT_OPC_DISCONNECTED,
367 __bt_free_sending_info(sending_info);
370 _bt_opp_client_event_deinit();
372 /* Operate remain works */
373 if (g_slist_length(transfer_list) > 0) {
374 bt_sending_data_t *data = NULL;
376 data = transfer_list->data;
380 transfer_list = g_slist_remove(transfer_list, data);
382 BT_DBG("calling __bt_opp_client_start_sending");
384 if (__bt_opp_client_start_sending(data->request_id,
385 data->address, data->file_path,
386 data->file_count) != BLUETOOTH_ERROR_NONE) {
393 g_slist_free_full(transfer_list,
394 (GDestroyNotify)__bt_free_sending_data);
395 transfer_list = NULL;
402 static int _bt_remove_session()
404 GDBusConnection *g_conn;
405 GDBusProxy *session_proxy;
408 g_conn = _bt_gdbus_get_system_gconn();
409 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
410 retv_if(sending_info->session_path == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
412 session_proxy = g_dbus_proxy_new_sync(g_conn, G_DBUS_PROXY_FLAGS_NONE,
413 NULL, BT_OBEXD_DBUS_NAME,
415 BT_OBEX_CLIENT_INTERFACE,
418 retv_if(session_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
420 g_dbus_proxy_call(session_proxy, "RemoveSession",
421 g_variant_new("(o)", sending_info->session_path),
422 G_DBUS_CALL_FLAGS_NONE,
424 (GAsyncReadyCallback)__bt_sending_release_cb,
427 return BLUETOOTH_ERROR_NONE;
430 static gboolean __bt_sending_release()
434 retv_if(sending_info == NULL, FALSE);
436 retv_if(_bt_remove_session() != BLUETOOTH_ERROR_NONE, FALSE);
442 void _bt_opc_disconnected(const char *session_path)
445 GVariant *param = NULL;
446 ret_if(sending_info == NULL);
448 if (g_strcmp0(sending_info->session_path,
449 session_path) != 0) {
450 BT_INFO("Path mismatch, previous transfer failed! Returning");
454 if (sending_info->transfer_info) {
455 if (sending_info->transfer_info->transfer_status == BT_TRANSFER_STATUS_PROGRESS ||
456 sending_info->transfer_info->transfer_status == BT_TRANSFER_STATUS_STARTED) {
457 BT_INFO("Abnormal termination");
458 param = g_variant_new("(issti)", sending_info->result,
459 sending_info->address,
460 sending_info->transfer_info->file_name,
461 sending_info->transfer_info->size,
462 sending_info->request_id);
463 _bt_send_event(BT_OPP_CLIENT_EVENT,
464 BLUETOOTH_EVENT_OPC_TRANSFER_COMPLETE,
466 __bt_free_transfer_info(sending_info->transfer_info);
469 param = g_variant_new("(isi)", sending_info->result,
470 sending_info->address,
471 sending_info->request_id);
472 _bt_send_event(BT_OPP_CLIENT_EVENT,
473 BLUETOOTH_EVENT_OPC_DISCONNECTED,
476 __bt_free_sending_info(sending_info);
482 static void __bt_send_file_cb(GDBusProxy *proxy,
483 GAsyncResult *res, gpointer user_data)
486 GVariant *value = NULL;
487 GError *error = NULL;
488 char *session_path = NULL;
489 const char *transfer_name = NULL;
490 const char *file_name = NULL;
492 GVariantIter *iter = NULL;
493 value = g_dbus_proxy_call_finish(proxy, res, &error);
495 g_dbus_error_strip_remote_error(error);
496 BT_ERR("%s", error->message);
497 /* If Obex is not able to open a file then continue with other if any */
498 if (g_strcmp0("Unable to open file", error->message) == 0) {
499 GVariant *param = NULL;
502 BT_ERR("Unable to open file [%s]", sending_info->file_name_array[file_offset]);
504 param = g_variant_new("(issti)", BLUETOOTH_ERROR_NOT_FOUND,
505 sending_info->address,
506 sending_info->file_name_array[file_offset],
508 sending_info->request_id);
509 _bt_send_event(BT_OPP_CLIENT_EVENT,
510 BLUETOOTH_EVENT_OPC_TRANSFER_STARTED,
513 param = g_variant_new("(issti)", BLUETOOTH_ERROR_NOT_FOUND,
514 sending_info->address,
515 sending_info->file_name_array[file_offset],
517 sending_info->request_id);
518 _bt_send_event(BT_OPP_CLIENT_EVENT,
519 BLUETOOTH_EVENT_OPC_TRANSFER_COMPLETE,
523 g_object_unref(proxy);
530 g_object_unref(proxy);
533 g_variant_get(value, "(oa{sv})", &session_path, &iter);
534 g_variant_unref(value);
537 __bt_free_transfer_info(sending_info->transfer_info);
539 sending_info->transfer_info = g_malloc0(sizeof(bt_transfer_info_t));
545 while (g_variant_iter_loop(iter, "{sv}", &key, &val)) {
546 if (g_strcmp0(key, "Name") == 0)
547 transfer_name = g_variant_dup_string(val, &len);
548 else if (g_strcmp0(key, "Filename") == 0)
549 file_name = g_variant_dup_string(val, &len);
550 else if (g_strcmp0(key, "Size") == 0)
551 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 = NULL;
578 if (sending_info == NULL)
580 if (file_offset < sending_info->file_count) {
581 /* Get the session bus. */
582 g_conn = _bt_gdbus_get_system_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 (headed_plugin_info->plugin_headed_enabled) {
592 if (headed_plugin_info->headed_plugin->bt_get_mime_type(sending_info->file_name_array[file_offset],
593 &mime_type) == BLUETOOTH_ERROR_NONE) {
594 BT_DBG("MLME type = %s", mime_type);
596 /* For IOPT compliance, change "text/x-iMelody" to "audio/imelody"
597 * because few devices(multimedia players) reject the OPP put for text objects
598 * since they support only multimedia files exchange */
599 if (!strcasecmp(mime_type, "text/x-iMelody")) {
600 strncpy(mime_type, "audio/imelody", BT_MIME_TYPE_MAX_LEN);
601 BT_DBG("over writing mime type to = %s", mime_type);
603 if (!strcasecmp(mime_type, "text/vcard")) {
604 strncpy(mime_type, "text/x-vcard", BT_MIME_TYPE_MAX_LEN);
605 BT_DBG("over writing mime type to = %s", mime_type);
610 BT_DBG("Calling SendFile");
611 g_dbus_proxy_call(client_proxy, "SendFile",
612 g_variant_new("(ss)", sending_info->file_name_array[file_offset],
614 G_DBUS_CALL_FLAGS_NONE,
616 (GAsyncReadyCallback)__bt_send_file_cb,
619 BT_ERR("Calling SendFile failed: [%s]\n", err->message);
627 __bt_sending_release();
634 static void __bt_create_session_cb(GDBusProxy *proxy,
635 GAsyncResult *res, gpointer user_data)
639 GError *error = NULL;
641 int result = BLUETOOTH_ERROR_NONE;
642 char *session_path = NULL;
643 GVariant *param = NULL;
645 value = g_dbus_proxy_call_finish(proxy, res, &error);
647 g_variant_get(value, "(o)", &session_path);
648 g_variant_unref(value);
652 BT_ERR("%s", error->message);
653 g_clear_error(&error);
655 result = BLUETOOTH_ERROR_INTERNAL;
657 BT_DBG("Session created");
658 if (sending_info != NULL)
659 sending_info->session_path = g_strdup(session_path);
661 g_free(session_path);
662 g_object_unref(proxy);
663 ret_if(sending_info == NULL);
665 sending_info->result = result;
666 param = g_variant_new("(isi)", result,
667 sending_info->address,
668 sending_info->request_id);
669 /* Send the event in only error none case */
670 _bt_send_event(BT_OPP_CLIENT_EVENT,
671 BLUETOOTH_EVENT_OPC_CONNECTED,
674 if (result != BLUETOOTH_ERROR_NONE) {
675 BT_ERR("Calling __bt_sending_release");
676 gboolean ret = __bt_sending_release();
678 __bt_free_sending_info(sending_info);
682 BT_DBG("ReleaseSession Not called");
683 /* Operate remain works */
684 if (g_slist_length(transfer_list) > 0) {
685 bt_sending_data_t *data = NULL;
687 data = transfer_list->data;
688 ret_if(data == NULL);
690 transfer_list = g_slist_remove(transfer_list, data);
692 BT_DBG("calling __bt_opp_client_start_sending");
694 if (__bt_opp_client_start_sending(data->request_id,
695 data->address, data->file_path,
696 data->file_count) != BLUETOOTH_ERROR_NONE) {
697 BT_ERR("Sending Enqueued Transfer Failed");
702 BT_DBG("Calling sending_files");
709 static int __bt_opp_client_start_sending(int request_id, char *address,
710 char **file_name_array, int file_count)
712 GVariantBuilder *builder;
714 GDBusConnection *g_conn;
715 GDBusProxy *client_proxy;
716 GError *error = NULL;
719 BT_CHECK_PARAMETER(address, return);
720 BT_CHECK_PARAMETER(file_name_array, return);
722 /* Get the session bus. */
723 g_conn = _bt_gdbus_get_system_gconn();
724 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
726 client_proxy = g_dbus_proxy_new_sync(g_conn, G_DBUS_PROXY_FLAGS_NONE,
727 NULL, BT_OBEX_SERVICE_NAME,
729 BT_OBEX_CLIENT_INTERFACE,
733 BT_ERR("Unable to create client proxy: %s", error->message);
734 g_clear_error(&error);
737 retv_if(client_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
739 builder = g_variant_builder_new(
740 G_VARIANT_TYPE("a{sv}"));
742 g_variant_builder_add(builder, "{sv}", "Target",
743 g_variant_new_string("OPP"));
745 __bt_free_sending_info(sending_info);
747 sending_info = g_malloc0(sizeof(bt_sending_info_t));
748 sending_info->address = g_strdup(address);
749 sending_info->request_id = request_id;
751 sending_info->file_count = file_count;
752 sending_info->file_offset = 0;
753 sending_info->file_name_array = g_new0(char *, file_count + 1);
755 for (i = 0; i < file_count; i++) {
756 sending_info->file_name_array[i] = g_strdup(file_name_array[i]);
757 BT_DBG("file[%d]: %s", i, sending_info->file_name_array[i]);
760 _bt_opp_client_event_deinit();
761 _bt_opp_client_event_init();
762 //_bt_obex_client_started(agent_path);
764 BT_DBG("Adapter Status %d", _bt_adapter_get_status());
765 if (_bt_adapter_get_status() == BT_ACTIVATED) {
766 BT_DBG("Going to call CreateSession");
767 g_dbus_proxy_call(client_proxy, "CreateSession",
768 g_variant_new("(sa{sv})", address, builder),
769 G_DBUS_CALL_FLAGS_NONE,
771 (GAsyncReadyCallback)__bt_create_session_cb,
774 GVariant *param = g_variant_new("(isi)", BLUETOOTH_ERROR_INTERNAL,
775 sending_info->address, sending_info->request_id);
777 BT_DBG("Address[%s] RequestID[%d]", sending_info->address, sending_info->request_id);
778 _bt_send_event(BT_OPP_CLIENT_EVENT, BLUETOOTH_EVENT_OPC_CONNECTED,
780 __bt_free_sending_info(sending_info);
783 g_variant_builder_unref(builder);
787 return BLUETOOTH_ERROR_NONE;
790 int _bt_opp_client_push_files(int request_id, GDBusMethodInvocation *context,
791 bluetooth_device_address_t *remote_address,
792 char **file_path, int file_count)
795 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
796 bt_sending_data_t *data;
798 GVariant *out_param1 = NULL;
800 int result = BLUETOOTH_ERROR_NONE;
803 BT_CHECK_PARAMETER(remote_address, return);
804 BT_CHECK_PARAMETER(file_path, return);
806 /* Implement the queue */
807 _bt_convert_addr_type_to_string(address, remote_address->addr);
809 if (sending_info == NULL) {
810 result = __bt_opp_client_start_sending(request_id,
811 address, file_path, file_count);
812 if (result != BLUETOOTH_ERROR_NONE)
815 /* Insert data in the queue */
816 data = g_malloc0(sizeof(bt_sending_data_t));
817 data->file_path = g_new0(char *, file_count + 1);
818 data->address = g_strdup(address);
819 data->file_count = file_count;
820 data->request_id = request_id;
822 for (i = 0; i < file_count; i++) {
823 data->file_path[i] = g_strdup(file_path[i]);
824 DBG_SECURE("file[%d]: %s", i, data->file_path[i]);
827 transfer_list = g_slist_append(transfer_list, data);
830 out_param1 = g_variant_new_from_data((const GVariantType *)"ay",
831 &request_id, sizeof(int),
835 g_dbus_method_invocation_return_value(context,
836 g_variant_new("(iv)", result, out_param1));
843 int _bt_opp_client_cancel_push(void)
848 int result = BLUETOOTH_ERROR_CANCEL_BY_USER;
849 GVariant *ret = NULL;
850 GVariant *param = NULL;
851 retv_if(sending_info == NULL, BLUETOOTH_ERROR_NOT_IN_OPERATION);
853 sending_info->is_canceled = TRUE;
854 sending_info->result = result;
856 if (sending_info->transfer_info) {
858 ret = g_dbus_proxy_call_sync(sending_info->transfer_info->proxy,
860 G_DBUS_CALL_FLAGS_NONE, -1,
864 BT_ERR("Cancel Error: %s\n", err->message);
868 g_variant_unref(ret);
871 param = g_variant_new("(issti)", result,
872 sending_info->address,
873 sending_info->transfer_info->file_name,
874 sending_info->transfer_info->size,
875 sending_info->request_id);
876 _bt_send_event(BT_OPP_CLIENT_EVENT,
877 BLUETOOTH_EVENT_OPC_TRANSFER_COMPLETE,
880 if (result == BLUETOOTH_ERROR_CANCEL_BY_USER) {
881 BT_ERR("result is not BLUETOOTH_ERROR_NONE");
882 __bt_sending_release();
887 g_idle_add(__bt_cancel_push_cb, NULL);
892 return BLUETOOTH_ERROR_NONE;
895 int _bt_opp_client_cancel_all_transfers(void)
899 g_slist_free_full(transfer_list,
900 (GDestroyNotify)__bt_free_sending_data);
902 transfer_list = NULL;
905 _bt_opp_client_cancel_push();
907 return BLUETOOTH_ERROR_NONE;
910 int _bt_opp_client_is_sending(gboolean *sending)
912 BT_CHECK_PARAMETER(sending, return);
914 *sending = sending_info ? TRUE : FALSE;
916 return BLUETOOTH_ERROR_NONE;
919 void _bt_opp_client_check_pending_transfer(const char *address)
923 int result = BLUETOOTH_ERROR_CANCEL;
924 GVariant *param = NULL;
925 ret_if(sending_info == NULL);
926 ret_if(sending_info->transfer_info == NULL);
928 if (g_strcmp0(sending_info->address, address) == 0) {
929 BT_INFO("Address Match.Cancel current transfer");
930 sending_info->transfer_info->transfer_status = BT_TRANSFER_STATUS_COMPLETED;
931 sending_info->result = result;
933 if (!sending_info->is_canceled) {
934 param = g_variant_new("(issti)", result,
935 sending_info->address,
936 sending_info->transfer_info->file_name,
937 sending_info->transfer_info->size,
938 sending_info->request_id);
939 _bt_send_event(BT_OPP_CLIENT_EVENT,
940 BLUETOOTH_EVENT_OPC_TRANSFER_COMPLETE,
942 __bt_free_transfer_info(sending_info->transfer_info);
943 sending_info->transfer_info = NULL;
944 /* Reset the file offset as we will cancelled remaining files also */
947 param = g_variant_new("(isi)", sending_info->result,
948 sending_info->address,
949 sending_info->request_id);
950 _bt_send_event(BT_OPP_CLIENT_EVENT,
951 BLUETOOTH_EVENT_OPC_DISCONNECTED,
954 __bt_sending_release();
959 int _bt_opp_get_client_progress(guint8 *progress)
961 if (sending_info == NULL || sending_info->transfer_info == NULL) {
962 BT_ERR("No Active Outbound transfer");
963 return BLUETOOTH_ERROR_NOT_FOUND;
966 *progress = (int)(((double)sending_info->transfer_info->progress /
967 sending_info->transfer_info->size) * 100);
969 BT_DBG("Percentage: %d", *progress);
970 return BLUETOOTH_ERROR_NONE;
973 void _bt_cancel_queued_transfers(void)
975 bt_sending_data_t *data = NULL;
976 GVariant *param = NULL;
978 BT_INFO("Cancel queued Transfers:: Length of transfer list is %d",
979 g_slist_length(transfer_list));
981 while (transfer_list) {
982 data = transfer_list->data;
983 param = g_variant_new("(isi)", BLUETOOTH_ERROR_INTERNAL,
984 data->address, data->request_id);
986 BT_DBG("Address[%s] RequestID[%d]", data->address, data->request_id);
987 _bt_send_event(BT_OPP_CLIENT_EVENT, BLUETOOTH_EVENT_OPC_CONNECTED,
990 transfer_list = g_slist_remove(transfer_list, data);