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-core-adapter.h"
35 #define BT_MIME_TYPE_MAX_LEN 20
37 static GSList *transfer_list = NULL;
38 static 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;
159 previous_progress = (int)(((gdouble)sending_info->transfer_info->progress /(gdouble)size) * 100);
161 previous_progress = 0;
163 if (percentage_progress == previous_progress &&
164 sending_info->transfer_info->progress) {
165 sending_info->transfer_info->progress = transferred;
168 BT_DBG("Sending progress [prev %d] [curr %d]",
169 previous_progress, percentage_progress);
171 sending_info->transfer_info->progress = transferred;
173 /* Send the event in only error none case */
174 param = g_variant_new("(istii)", result,
175 sending_info->transfer_info->file_name,
176 sending_info->transfer_info->size,
178 sending_info->request_id);
181 _bt_send_event(BT_OPP_CLIENT_EVENT,
182 BLUETOOTH_EVENT_OPC_TRANSFER_PROGRESS,
189 gboolean _bt_obex_client_completed(const char *transfer_path, gboolean success)
193 int result = BLUETOOTH_ERROR_NONE;
194 GVariant *param = NULL;
195 retv_if(sending_info == NULL, TRUE);
196 retv_if(sending_info->transfer_info == NULL, TRUE);
198 if (g_strcmp0(sending_info->transfer_info->transfer_path,
199 transfer_path) != 0) {
200 BT_INFO("Path mismatch, previous transfer failed! Returning");
204 result = (success == TRUE) ? BLUETOOTH_ERROR_NONE : BLUETOOTH_ERROR_CANCEL;
206 sending_info->transfer_info->transfer_status = BT_TRANSFER_STATUS_COMPLETED;
207 sending_info->result = result;
209 if (!success) { /*In case of remote device reject, we need to send BLUETOOTH_EVENT_OPC_DISCONNECTED */
210 BT_DBG("completed with error");
211 if (!sending_info->is_canceled) {
212 param = g_variant_new("(issti)", result,
213 sending_info->address,
214 sending_info->transfer_info->file_name,
215 sending_info->transfer_info->size,
216 sending_info->request_id);
217 _bt_send_event(BT_OPP_CLIENT_EVENT,
218 BLUETOOTH_EVENT_OPC_TRANSFER_COMPLETE,
220 __bt_free_transfer_info(sending_info->transfer_info);
221 sending_info->transfer_info = NULL;
222 /* Reset the file offset as we will cancelled remaining files also */
225 param = g_variant_new("(isi)", sending_info->result,
226 sending_info->address,
227 sending_info->request_id);
228 _bt_send_event(BT_OPP_CLIENT_EVENT,
229 BLUETOOTH_EVENT_OPC_DISCONNECTED,
231 __bt_sending_release();
232 /* Sending info should not freed after sending_release it's
233 * already freed in that API and if any pending request is
234 * present then it recreate sending_info again.
235 * And if we free it here then CreateSession method call will
236 * made but RemoveSession method call will not done.
239 BT_DBG("complete success");
240 /* Send the event in only error none case */
241 param = g_variant_new("(issti)", result,
242 sending_info->address,
243 sending_info->transfer_info->file_name,
244 sending_info->transfer_info->size,
245 sending_info->request_id);
246 _bt_send_event(BT_OPP_CLIENT_EVENT,
247 BLUETOOTH_EVENT_OPC_TRANSFER_COMPLETE,
249 __bt_free_transfer_info(sending_info->transfer_info);
250 sending_info->transfer_info = NULL;
258 gboolean _bt_obex_client_started(const char *transfer_path)
262 int result = BLUETOOTH_ERROR_NONE;
263 GError *error = NULL;
264 GVariant *param = NULL;
265 GDBusConnection *g_conn;
266 GDBusProxy *properties_proxy;
267 GDBusProxy *transfer_proxy;
269 if (sending_info == NULL || sending_info->is_canceled == TRUE) {
270 result = BLUETOOTH_ERROR_CANCEL_BY_USER;
274 /* Get the session bus. */
275 g_conn = _bt_get_system_gconn();
276 retv_if(g_conn == NULL, FALSE);
277 properties_proxy = g_dbus_proxy_new_sync(g_conn, G_DBUS_PROXY_FLAGS_NONE,
278 NULL, BT_OBEXD_DBUS_NAME,
279 transfer_path, BT_PROPERTIES_INTERFACE,
282 retv_if(properties_proxy == NULL, FALSE);
284 sending_info->transfer_info->properties_proxy = properties_proxy;
286 transfer_proxy = g_dbus_proxy_new_sync(g_conn, G_DBUS_PROXY_FLAGS_NONE,
287 NULL, BT_OBEXD_DBUS_NAME,
288 transfer_path, BT_OBEX_TRANSFER_INTERFACE,
291 retv_if(transfer_proxy == NULL, FALSE);
293 sending_info->transfer_info->proxy = transfer_proxy;
295 sending_info->transfer_info->transfer_status = BT_TRANSFER_STATUS_STARTED;
296 sending_info->result = result;
298 param = g_variant_new("(issti)", result,
299 sending_info->address,
300 sending_info->transfer_info->file_name,
301 sending_info->transfer_info->size,
302 sending_info->request_id);
303 _bt_send_event(BT_OPP_CLIENT_EVENT,
304 BLUETOOTH_EVENT_OPC_TRANSFER_STARTED,
310 error = g_error_new(__bt_opc_error_quark(), BT_OBEX_AGENT_ERROR_CANCEL,
319 static void __bt_free_sending_data(gpointer data)
322 bt_sending_data_t *info = data;
324 ret_if(info == NULL);
326 for (i = 0; i < info->file_count; i++)
327 g_free(info->file_path[i]);
329 _bt_delete_request_id(info->request_id);
331 g_free(info->file_path);
332 g_free(info->address);
336 static void __bt_sending_release_cb(GDBusProxy *proxy,
337 GAsyncResult *res, gpointer user_data)
340 ret_if(sending_info == NULL);
342 GError *error = NULL;
343 int result = BLUETOOTH_ERROR_NONE;
344 GVariant *param = NULL;
345 GVariant *reply = NULL;
347 reply = g_dbus_proxy_call_finish(proxy, res, &error);
349 g_object_unref(proxy);
351 g_variant_unref(reply);
354 BT_ERR("%s", error->message);
357 result = BLUETOOTH_ERROR_INTERNAL;
360 BT_DBG("Session Removed");
363 sending_info->result = result;
364 param = g_variant_new("(isi)", sending_info->result,
365 sending_info->address,
366 sending_info->request_id);
367 /* Send the event in only error none case */
368 _bt_send_event(BT_OPP_CLIENT_EVENT,
369 BLUETOOTH_EVENT_OPC_DISCONNECTED,
372 __bt_free_sending_info(sending_info);
375 _bt_opp_client_event_deinit();
377 /* Operate remain works */
378 if (g_slist_length(transfer_list) > 0) {
379 bt_sending_data_t *data = NULL;
381 data = transfer_list->data;
385 transfer_list = g_slist_remove(transfer_list, data);
387 BT_DBG("calling __bt_opp_client_start_sending");
389 if (__bt_opp_client_start_sending(data->request_id,
390 data->address, data->file_path,
391 data->file_count) != BLUETOOTH_ERROR_NONE) {
398 g_slist_free_full(transfer_list,
399 (GDestroyNotify)__bt_free_sending_data);
400 transfer_list = NULL;
407 static int _bt_remove_session()
409 GDBusConnection *g_conn;
410 GDBusProxy *session_proxy;
413 g_conn = _bt_get_system_gconn();
414 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
415 retv_if(sending_info->session_path == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
417 session_proxy = g_dbus_proxy_new_sync(g_conn, G_DBUS_PROXY_FLAGS_NONE,
418 NULL, BT_OBEXD_DBUS_NAME,
420 BT_OBEX_CLIENT_INTERFACE,
423 retv_if(session_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
425 g_dbus_proxy_call(session_proxy, "RemoveSession",
426 g_variant_new("(o)", sending_info->session_path),
427 G_DBUS_CALL_FLAGS_NONE,
429 (GAsyncReadyCallback)__bt_sending_release_cb,
432 return BLUETOOTH_ERROR_NONE;
435 static gboolean __bt_sending_release()
439 retv_if(sending_info == NULL, FALSE);
441 retv_if(_bt_remove_session() != BLUETOOTH_ERROR_NONE, FALSE);
447 void _bt_opc_disconnected(const char *session_path)
450 GVariant *param = NULL;
451 ret_if(sending_info == NULL);
453 if (g_strcmp0(sending_info->session_path,
454 session_path) != 0) {
455 BT_INFO("Path mismatch, previous transfer failed! Returning");
459 if (sending_info->transfer_info) {
460 if (sending_info->transfer_info->transfer_status == BT_TRANSFER_STATUS_PROGRESS ||
461 sending_info->transfer_info->transfer_status == BT_TRANSFER_STATUS_STARTED) {
462 BT_INFO("Abnormal termination");
463 param = g_variant_new("(issti)", sending_info->result,
464 sending_info->address,
465 sending_info->transfer_info->file_name,
466 sending_info->transfer_info->size,
467 sending_info->request_id);
468 _bt_send_event(BT_OPP_CLIENT_EVENT,
469 BLUETOOTH_EVENT_OPC_TRANSFER_COMPLETE,
471 __bt_free_transfer_info(sending_info->transfer_info);
474 param = g_variant_new("(isi)", sending_info->result,
475 sending_info->address,
476 sending_info->request_id);
477 _bt_send_event(BT_OPP_CLIENT_EVENT,
478 BLUETOOTH_EVENT_OPC_DISCONNECTED,
481 __bt_free_sending_info(sending_info);
487 static void __bt_send_file_cb(GDBusProxy *proxy,
488 GAsyncResult *res, gpointer user_data)
491 GVariant *value = NULL;
492 GError *error = NULL;
493 char *session_path = NULL;
494 const char *transfer_name = NULL;
495 const char *file_name = NULL;
497 GVariantIter *iter = NULL;
498 value = g_dbus_proxy_call_finish(proxy, res, &error);
500 g_dbus_error_strip_remote_error(error);
501 BT_ERR("%s", error->message);
502 /* If Obex is not able to open a file then continue with other if any */
503 if (g_strcmp0("Unable to open file", error->message) == 0) {
504 GVariant *param = NULL;
507 BT_ERR("Unable to open file [%s]", sending_info->file_name_array[file_offset]);
509 param = g_variant_new("(issti)", BLUETOOTH_ERROR_NOT_FOUND,
510 sending_info->address,
511 sending_info->file_name_array[file_offset],
513 sending_info->request_id);
514 _bt_send_event(BT_OPP_CLIENT_EVENT,
515 BLUETOOTH_EVENT_OPC_TRANSFER_STARTED,
518 param = g_variant_new("(issti)", BLUETOOTH_ERROR_NOT_FOUND,
519 sending_info->address,
520 sending_info->file_name_array[file_offset],
522 sending_info->request_id);
523 _bt_send_event(BT_OPP_CLIENT_EVENT,
524 BLUETOOTH_EVENT_OPC_TRANSFER_COMPLETE,
528 g_object_unref(proxy);
535 g_object_unref(proxy);
538 g_variant_get(value, "(oa{sv})", &session_path, &iter);
539 g_variant_unref(value);
542 __bt_free_transfer_info(sending_info->transfer_info);
544 sending_info->transfer_info = g_malloc0(sizeof(bt_transfer_info_t));
550 while (g_variant_iter_loop(iter, "{sv}", &key, &val)) {
551 if (g_strcmp0(key, "Name") == 0)
552 transfer_name = g_variant_dup_string(val, &len);
553 else if (g_strcmp0(key, "Filename") == 0)
554 file_name = g_variant_dup_string(val, &len);
555 else if (g_strcmp0(key, "Size") == 0)
556 size = g_variant_get_uint64(val);
558 g_variant_iter_free(iter);
561 sending_info->transfer_info->transfer_name = g_strdup(transfer_name);
562 sending_info->transfer_info->file_name = g_strdup(file_name);
563 sending_info->transfer_info->size = size;
564 sending_info->transfer_info->progress = 0;
565 sending_info->transfer_info->transfer_path = session_path;
566 sending_info->transfer_info->transfer_status = BT_TRANSFER_STATUS_QUEUED;
567 sending_info->result = BLUETOOTH_ERROR_NONE;
570 g_free((gchar *)transfer_name);
571 g_free((gchar *)file_name);
574 void _bt_sending_files(void)
579 GDBusConnection *g_conn;
580 GDBusProxy *client_proxy;
581 char *mime_type = NULL;
583 if (sending_info == NULL)
585 if (file_offset < sending_info->file_count) {
586 /* Get the session bus. */
587 g_conn = _bt_get_system_gconn();
588 ret_if(g_conn == NULL);
590 client_proxy = g_dbus_proxy_new_sync(g_conn, G_DBUS_PROXY_FLAGS_NONE,
591 NULL, BT_OBEXD_DBUS_NAME,
592 sending_info->session_path,
593 BT_OBEX_OBJECT_PUSH_INTERFACE,
595 ret_if(client_proxy == NULL);
596 if (headed_plugin_info->plugin_headed_enabled) {
597 if (headed_plugin_info->headed_plugin->bt_get_mime_type(sending_info->file_name_array[file_offset],
598 &mime_type) == BLUETOOTH_ERROR_NONE) {
599 BT_DBG("MLME type = %s", mime_type);
601 /* For IOPT compliance, change "text/x-iMelody" to "audio/imelody"
602 * because few devices(multimedia players) reject the OPP put for text objects
603 * since they support only multimedia files exchange */
604 if (!strcasecmp(mime_type, "text/x-iMelody")) {
605 strncpy(mime_type, "audio/imelody", BT_MIME_TYPE_MAX_LEN);
606 BT_DBG("over writing mime type to = %s", mime_type);
608 if (!strcasecmp(mime_type, "text/vcard")) {
609 strncpy(mime_type, "text/x-vcard", BT_MIME_TYPE_MAX_LEN);
610 BT_DBG("over writing mime type to = %s", mime_type);
615 BT_DBG("Calling SendFile");
616 g_dbus_proxy_call(client_proxy, "SendFile",
617 g_variant_new("(ss)", sending_info->file_name_array[file_offset],
619 G_DBUS_CALL_FLAGS_NONE,
621 (GAsyncReadyCallback)__bt_send_file_cb,
624 BT_ERR("Calling SendFile failed: [%s]\n", err->message);
632 __bt_sending_release();
639 static void __bt_create_session_cb(GDBusProxy *proxy,
640 GAsyncResult *res, gpointer user_data)
644 GError *error = NULL;
646 int result = BLUETOOTH_ERROR_NONE;
647 char *session_path = NULL;
648 GVariant *param = NULL;
650 value = g_dbus_proxy_call_finish(proxy, res, &error);
652 g_variant_get(value, "(o)", &session_path);
653 g_variant_unref(value);
657 BT_ERR("%s", error->message);
658 g_clear_error(&error);
660 result = BLUETOOTH_ERROR_INTERNAL;
662 BT_DBG("Session created");
663 if (sending_info != NULL)
664 sending_info->session_path = g_strdup(session_path);
666 g_free(session_path);
667 g_object_unref(proxy);
668 ret_if(sending_info == NULL);
670 sending_info->result = result;
671 param = g_variant_new("(isi)", result,
672 sending_info->address,
673 sending_info->request_id);
674 /* Send the event in only error none case */
675 _bt_send_event(BT_OPP_CLIENT_EVENT,
676 BLUETOOTH_EVENT_OPC_CONNECTED,
679 if (result != BLUETOOTH_ERROR_NONE) {
680 BT_ERR("Calling __bt_sending_release");
681 gboolean ret = __bt_sending_release();
683 __bt_free_sending_info(sending_info);
687 BT_DBG("ReleaseSession Not called");
688 /* Operate remain works */
689 if (g_slist_length(transfer_list) > 0) {
690 bt_sending_data_t *data = NULL;
692 data = transfer_list->data;
693 ret_if(data == NULL);
695 transfer_list = g_slist_remove(transfer_list, data);
697 BT_DBG("calling __bt_opp_client_start_sending");
699 if (__bt_opp_client_start_sending(data->request_id,
700 data->address, data->file_path,
701 data->file_count) != BLUETOOTH_ERROR_NONE) {
702 BT_ERR("Sending Enqueued Transfer Failed");
707 BT_DBG("Calling sending_files");
714 static int __bt_opp_client_start_sending(int request_id, char *address,
715 char **file_name_array, int file_count)
717 GVariantBuilder *builder;
719 GDBusConnection *g_conn;
720 GDBusProxy *client_proxy;
721 GError *error = NULL;
724 BT_CHECK_PARAMETER(address, return);
725 BT_CHECK_PARAMETER(file_name_array, return);
727 /* Get the session bus. */
728 g_conn = _bt_get_system_gconn();
729 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
731 client_proxy = g_dbus_proxy_new_sync(g_conn, G_DBUS_PROXY_FLAGS_NONE,
732 NULL, BT_OBEX_SERVICE_NAME,
734 BT_OBEX_CLIENT_INTERFACE,
738 BT_ERR("Unable to create client proxy: %s", error->message);
739 g_clear_error(&error);
742 retv_if(client_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
744 builder = g_variant_builder_new(
745 G_VARIANT_TYPE("a{sv}"));
747 g_variant_builder_add(builder, "{sv}", "Target",
748 g_variant_new_string("OPP"));
750 __bt_free_sending_info(sending_info);
752 sending_info = g_malloc0(sizeof(bt_sending_info_t));
753 sending_info->address = g_strdup(address);
754 sending_info->request_id = request_id;
756 sending_info->file_count = file_count;
757 sending_info->file_offset = 0;
758 sending_info->file_name_array = g_new0(char *, file_count + 1);
760 for (i = 0; i < file_count; i++) {
761 sending_info->file_name_array[i] = g_strdup(file_name_array[i]);
762 BT_DBG("file[%d]: %s", i, sending_info->file_name_array[i]);
765 _bt_opp_client_event_deinit();
766 _bt_opp_client_event_init();
767 //_bt_obex_client_started(agent_path);
769 BT_DBG("Adapter Status %d", _bt_adapter_get_status());
770 if (_bt_adapter_get_status() == BT_ACTIVATED) {
771 BT_DBG("Going to call CreateSession");
772 g_dbus_proxy_call(client_proxy, "CreateSession",
773 g_variant_new("(sa{sv})", address, builder),
774 G_DBUS_CALL_FLAGS_NONE,
776 (GAsyncReadyCallback)__bt_create_session_cb,
779 GVariant *param = g_variant_new("(isi)", BLUETOOTH_ERROR_INTERNAL,
780 sending_info->address, sending_info->request_id);
782 BT_DBG("Address[%s] RequestID[%d]", sending_info->address, sending_info->request_id);
783 _bt_send_event(BT_OPP_CLIENT_EVENT, BLUETOOTH_EVENT_OPC_CONNECTED,
785 __bt_free_sending_info(sending_info);
788 g_variant_builder_unref(builder);
792 return BLUETOOTH_ERROR_NONE;
795 int _bt_opp_client_push_files(int request_id, GDBusMethodInvocation *context,
796 bluetooth_device_address_t *remote_address,
797 char **file_path, int file_count)
800 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
801 bt_sending_data_t *data;
803 GVariant *out_param1 = NULL;
805 int result = BLUETOOTH_ERROR_NONE;
808 BT_CHECK_PARAMETER(remote_address, return);
809 BT_CHECK_PARAMETER(file_path, return);
811 /* Implement the queue */
812 _bt_convert_addr_type_to_string(address, remote_address->addr);
814 if (sending_info == NULL) {
815 result = __bt_opp_client_start_sending(request_id,
816 address, file_path, file_count);
817 if (result != BLUETOOTH_ERROR_NONE)
820 /* Insert data in the queue */
821 data = g_malloc0(sizeof(bt_sending_data_t));
822 data->file_path = g_new0(char *, file_count + 1);
823 data->address = g_strdup(address);
824 data->file_count = file_count;
825 data->request_id = request_id;
827 for (i = 0; i < file_count; i++) {
828 data->file_path[i] = g_strdup(file_path[i]);
829 DBG_SECURE("file[%d]: %s", i, data->file_path[i]);
832 transfer_list = g_slist_append(transfer_list, data);
835 out_param1 = g_variant_new_from_data((const GVariantType *)"ay",
836 &request_id, sizeof(int),
840 g_dbus_method_invocation_return_value(context,
841 g_variant_new("(iv)", result, out_param1));
848 int _bt_opp_client_cancel_push(void)
853 int result = BLUETOOTH_ERROR_CANCEL_BY_USER;
854 GVariant *ret = NULL;
855 GVariant *param = NULL;
856 retv_if(sending_info == NULL, BLUETOOTH_ERROR_NOT_IN_OPERATION);
858 sending_info->is_canceled = TRUE;
859 sending_info->result = result;
861 if (sending_info->transfer_info) {
863 ret = g_dbus_proxy_call_sync(sending_info->transfer_info->proxy,
865 G_DBUS_CALL_FLAGS_NONE, -1,
869 BT_ERR("Cancel Error: %s\n", err->message);
873 g_variant_unref(ret);
876 param = g_variant_new("(issti)", result,
877 sending_info->address,
878 sending_info->transfer_info->file_name,
879 sending_info->transfer_info->size,
880 sending_info->request_id);
881 _bt_send_event(BT_OPP_CLIENT_EVENT,
882 BLUETOOTH_EVENT_OPC_TRANSFER_COMPLETE,
885 if (result == BLUETOOTH_ERROR_CANCEL_BY_USER) {
886 BT_ERR("result is not BLUETOOTH_ERROR_NONE");
887 __bt_sending_release();
892 g_idle_add(__bt_cancel_push_cb, NULL);
897 return BLUETOOTH_ERROR_NONE;
900 int _bt_opp_client_cancel_all_transfers(void)
904 g_slist_free_full(transfer_list,
905 (GDestroyNotify)__bt_free_sending_data);
907 transfer_list = NULL;
910 _bt_opp_client_cancel_push();
912 return BLUETOOTH_ERROR_NONE;
915 int _bt_opp_client_is_sending(gboolean *sending)
917 BT_CHECK_PARAMETER(sending, return);
919 *sending = sending_info ? TRUE : FALSE;
921 return BLUETOOTH_ERROR_NONE;
924 void _bt_opp_client_check_pending_transfer(const char *address)
928 int result = BLUETOOTH_ERROR_CANCEL;
929 GVariant *param = NULL;
930 ret_if(sending_info == NULL);
931 ret_if(sending_info->transfer_info == NULL);
933 if (g_strcmp0(sending_info->address, address) == 0) {
934 BT_INFO("Address Match.Cancel current transfer");
935 sending_info->transfer_info->transfer_status = BT_TRANSFER_STATUS_COMPLETED;
936 sending_info->result = result;
938 if (!sending_info->is_canceled) {
939 param = g_variant_new("(issti)", result,
940 sending_info->address,
941 sending_info->transfer_info->file_name,
942 sending_info->transfer_info->size,
943 sending_info->request_id);
944 _bt_send_event(BT_OPP_CLIENT_EVENT,
945 BLUETOOTH_EVENT_OPC_TRANSFER_COMPLETE,
947 __bt_free_transfer_info(sending_info->transfer_info);
948 sending_info->transfer_info = NULL;
949 /* Reset the file offset as we will cancelled remaining files also */
952 param = g_variant_new("(isi)", sending_info->result,
953 sending_info->address,
954 sending_info->request_id);
955 _bt_send_event(BT_OPP_CLIENT_EVENT,
956 BLUETOOTH_EVENT_OPC_DISCONNECTED,
959 __bt_sending_release();
964 int _bt_opp_get_client_progress(guint8 *progress)
966 if (sending_info == NULL || sending_info->transfer_info == NULL) {
967 BT_ERR("No Active Outbound transfer");
968 return BLUETOOTH_ERROR_NOT_FOUND;
971 *progress = (int)(((double)sending_info->transfer_info->progress /
972 sending_info->transfer_info->size) * 100);
974 BT_DBG("Percentage: %d", *progress);
975 return BLUETOOTH_ERROR_NONE;
978 void _bt_cancel_queued_transfers(void)
980 bt_sending_data_t *data = NULL;
981 GVariant *param = NULL;
983 BT_INFO("Cancel queued Transfers:: Length of transfer list is %d",
984 g_slist_length(transfer_list));
986 while (transfer_list) {
987 data = transfer_list->data;
988 param = g_variant_new("(isi)", BLUETOOTH_ERROR_INTERNAL,
989 data->address, data->request_id);
991 BT_DBG("Address[%s] RequestID[%d]", data->address, data->request_id);
992 _bt_send_event(BT_OPP_CLIENT_EVENT, BLUETOOTH_EVENT_OPC_CONNECTED,
995 transfer_list = g_slist_remove(transfer_list, data);