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.
23 #ifdef TIZEN_DPM_ENABLE
24 #include "bt-service-dpm.h"
31 #include "bluetooth-api.h"
32 #include "bt-internal-types.h"
34 #include "bt-service-common.h"
35 #include "bt-service-event.h"
36 #include "bt-service-util.h"
37 #include "bt-service-obex-agent.h"
38 #include "bt-service-obex-server.h"
39 #include "bt-service-agent.h"
41 #define DBUS_TIMEOUT 20 * 1000 /* 20 Seconds */
42 #define BT_OBEX_SERVER_AGENT_PATH "/org/obex/server_agent"
44 #define BT_OBEX_SERVICE "org.bluez.obex"
45 #define BT_OBEX_MANAGER "org.bluez.obex.AgentManager1"
46 #define BT_OBEX_PATH "/org/bluez/obex"
48 #define BT_OBEX_PATH_PREFIX "/opt/usr/media"
49 #define BT_OBEX_DEFAULT_PATH "/opt/usr/home/owner/media"
50 #define BT_OBEX_PATH_MAX_LENGTH 255
66 GDBusMethodInvocation *reply_context;
73 unsigned char contact_auth_info[5];
86 bt_auth_info_t *auth_info;
87 bt_server_info_t *native_server;
88 bt_server_info_t *custom_server;
89 } bt_obex_agent_info_t;
97 static GSList *transfers;
98 static bt_obex_agent_info_t agent_info;
99 static GSList *session_list = NULL;
101 static bt_session_info_t *__bt_find_session_by_path(char *transfer_path)
104 bt_session_info_t *session;
106 retv_if(transfer_path == NULL, NULL);
108 for (l = session_list; l != NULL; l = l->next) {
114 if (g_strcmp0(session->path, transfer_path) == 0)
121 static GQuark __bt_obex_error_quark(void)
123 static GQuark quark = 0;
125 quark = g_quark_from_static_string("agent");
130 static bt_transfer_info_t *__bt_find_transfer_by_id(int transfer_id)
133 bt_transfer_info_t *transfer;
135 for (l = transfers; l != NULL; l = l->next) {
138 if (transfer == NULL)
141 if (transfer->transfer_id == transfer_id)
148 bt_transfer_info_t *__bt_find_transfer_by_address(const char *address)
152 bt_transfer_info_t *transfer;
154 retv_if(address == NULL, NULL);
156 for (l = transfers; l != NULL; l = l->next) {
159 if (transfer == NULL)
162 if (g_strcmp0(transfer->address, address) == 0)
169 static bt_transfer_info_t *__bt_find_transfer_by_path(const char *transfer_path)
172 bt_transfer_info_t *transfer;
174 retv_if(transfer_path == NULL, NULL);
176 for (l = transfers; l != NULL; l = l->next) {
179 if (transfer == NULL)
182 if (g_strcmp0(transfer->path, transfer_path) == 0)
189 static void __bt_free_server_info(bt_server_info_t *server_info)
191 ret_if(server_info == NULL);
193 g_free(server_info->sender);
194 g_free(server_info->dest_path);
198 static void __bt_free_auth_info(bt_auth_info_t *auto_info)
200 ret_if(auto_info == NULL);
202 g_free(auto_info->filename);
203 g_free(auto_info->transfer_path);
204 g_free(auto_info->device_name);
205 g_free(auto_info->address);
209 static void __bt_free_transfer_info(bt_transfer_info_t *transfer_info)
211 ret_if(transfer_info == NULL);
213 g_free(transfer_info->path);
214 g_free(transfer_info->filename);
215 g_free(transfer_info->file_path);
216 g_free(transfer_info->type);
217 g_free(transfer_info->device_name);
218 g_free(transfer_info->address);
219 g_free(transfer_info);
222 void _bt_obex_check_pending_transfer(const char *address)
225 GVariant *param = NULL;
226 bt_transfer_info_t *transfer_info = __bt_find_transfer_by_address(address);
227 if (transfer_info != NULL) {
228 int result = BLUETOOTH_ERROR_CANCEL;
229 param = g_variant_new("(issssstii)", result,
230 transfer_info->filename,
232 transfer_info->device_name,
233 transfer_info->file_path,
234 transfer_info->address,
235 transfer_info->file_size,
236 transfer_info->transfer_id,
237 agent_info.server_type);
238 _bt_send_event(BT_OPP_SERVER_EVENT,
239 BLUETOOTH_EVENT_OBEX_SERVER_TRANSFER_COMPLETED,
241 transfers = g_slist_remove(transfers, transfer_info);
242 __bt_free_transfer_info(transfer_info);
247 static char *__bt_get_remote_device_name(const char *bdaddress)
249 char *device_path = NULL;
252 GVariant *result = NULL;
254 GDBusProxy *device_proxy;
255 GDBusConnection *conn;
257 retv_if(bdaddress == NULL, NULL);
259 device_path = _bt_get_device_object_path((char *)bdaddress);
260 retv_if(device_path == NULL, NULL);
262 conn = _bt_gdbus_get_system_gconn();
263 retv_if(conn == NULL, NULL);
264 BT_INFO("Device_path %s", device_path);
265 device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
268 BT_PROPERTIES_INTERFACE,
272 retv_if(device_proxy == NULL, NULL);
274 result = g_dbus_proxy_call_sync(device_proxy, "GetAll",
275 g_variant_new("(s)", BT_DEVICE_INTERFACE),
276 G_DBUS_CALL_FLAGS_NONE,
280 BT_ERR("DBus Error : %s", err->message);
284 if (result == NULL) {
285 BT_ERR("g_dbus_proxy_call_sync function return NULL");
288 g_variant_get(result, "(@a{sv})", &value);
291 GVariant *temp_value = g_variant_lookup_value(value, "Alias",
292 G_VARIANT_TYPE_STRING);
293 g_variant_get(temp_value, "s", &name);
295 g_variant_unref(temp_value);
298 DBG_SECURE("Alias Name [%s]", name);
300 temp_value = g_variant_lookup_value(value, "Name", G_VARIANT_TYPE_STRING);
301 g_variant_get(temp_value, "s", &name);
303 g_variant_unref(temp_value);
304 DBG_SECURE("Name = %s", name);
307 g_variant_unref(result);
308 g_object_unref(device_proxy);
312 static void __bt_get_remote_device_name_authinfo(const char *bdaddress,
313 char **device_name, unsigned char *auth_info)
315 char *device_path = NULL;
317 gboolean is_alias_set;
319 GVariant *result = NULL;
321 GDBusProxy *device_proxy;
322 GDBusConnection *conn;
324 ret_if(bdaddress == NULL);
326 device_path = _bt_get_device_object_path((char *)bdaddress);
327 ret_if(device_path == NULL);
329 conn = _bt_gdbus_get_system_gconn();
330 ret_if(conn == NULL);
331 BT_INFO("Device_path %s", device_path);
332 device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
335 BT_PROPERTIES_INTERFACE,
339 ret_if(device_proxy == NULL);
341 result = g_dbus_proxy_call_sync(device_proxy, "GetAll",
342 g_variant_new("(s)", BT_DEVICE_INTERFACE),
343 G_DBUS_CALL_FLAGS_NONE,
347 BT_ERR("DBus Error : %s", err->message);
351 if (result == NULL) {
352 BT_ERR("g_dbus_proxy_call_sync function return NULL");
355 g_variant_get(result, "(@a{sv})", &value);
358 GVariant *temp_value = g_variant_lookup_value(value, "Alias",
359 G_VARIANT_TYPE_STRING);
360 g_variant_get(temp_value, "s", &name);
362 g_variant_unref(temp_value);
365 DBG_SECURE("Alias Name [%s]", name);
367 temp_value = g_variant_lookup_value(value, "Name", G_VARIANT_TYPE_STRING);
368 g_variant_get(temp_value, "s", &name);
370 g_variant_unref(temp_value);
371 DBG_SECURE("Name = %s", name);
373 temp_value = g_variant_lookup_value(value, "IsAliasSet", G_VARIANT_TYPE_BOOLEAN);
375 is_alias_set = g_variant_get_boolean(temp_value);
376 g_variant_unref(temp_value);
378 is_alias_set = FALSE;
381 if (is_alias_set == FALSE)
382 __bt_get_auth_info(value, (char *)auth_info);
384 g_variant_unref(result);
385 g_object_unref(device_proxy);
387 *device_name = g_strdup(name);
392 static int __bt_get_transfer_id(const char *path)
398 tmp = strrchr(path, 'r') + 1;
399 retv_if(tmp == NULL, -1);
404 static GDBusProxy *__bt_get_transfer_proxy(const char *transfer_path)
406 GDBusConnection *conn;
410 conn = _bt_gdbus_get_session_gconn();
411 retv_if(conn == NULL, NULL);
413 proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
414 NULL, BT_OBEX_SERVICE_NAME,
416 BT_OBEX_TRANSFER_INTERFACE,
420 BT_ERR("Error : %s", err->message);
428 static GDBusProxy *__bt_get_transfer_properties_proxy(const char *transfer_path)
430 GDBusConnection *conn;
433 conn = _bt_gdbus_get_session_gconn();
434 retv_if(conn == NULL, NULL);
436 proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
437 NULL, BT_OBEX_SERVICE_NAME,
439 BT_PROPERTIES_INTERFACE,
442 BT_ERR("Error : %s", err->message);
449 static int __bt_get_transfer_properties(bt_transfer_info_t *transfer_info,
450 const char *transfer_path)
452 GDBusProxy *transfer_proxy;
453 GVariant *result = NULL;
455 GVariantIter *iter = NULL;
456 BT_CHECK_PARAMETER(transfer_info, return);
457 BT_CHECK_PARAMETER(transfer_path, return);
459 transfer_proxy = __bt_get_transfer_properties_proxy(transfer_path);
461 retv_if(transfer_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
463 result = g_dbus_proxy_call_sync(transfer_proxy, "GetAll",
464 g_variant_new("(s)", BT_OBEX_TRANSFER_INTERFACE),
465 G_DBUS_CALL_FLAGS_NONE,
470 BT_ERR("DBus Error : %s", err->message);
474 if (result == NULL) {
475 BT_ERR("g_dbus_proxy_call_sync function return NULL");
479 g_variant_get(result, "(a{sv})", &iter);
480 g_variant_unref(result);
485 while (g_variant_iter_loop(iter, "{sv}", &key, &val)) {
486 if (g_strcmp0(key, "Operation") == 0) {
487 transfer_info->type = g_variant_dup_string(val, &len);
488 } else if (g_strcmp0(key, "Name") == 0) {
489 transfer_info->filename = g_variant_dup_string(val, &len);
490 } else if (g_strcmp0(key, "Size") == 0) {
491 transfer_info->file_size = g_variant_get_uint64(val);
492 } else if (g_strcmp0(key, "Address") == 0) {
493 transfer_info->address = g_variant_dup_string(val, &len);
494 BT_INFO("addressss %s", transfer_info->address);
495 } else if (g_strcmp0(key, "Filename") == 0) {
496 transfer_info->file_path = g_variant_dup_string(val, &len);
497 if (!transfer_info->file_path)
498 transfer_info->file_path = g_strdup(transfer_info->filename);
501 g_variant_iter_free(iter);
503 if (transfer_info->address == NULL)
505 transfer_info->device_name = __bt_get_remote_device_name(transfer_info->address);
506 transfer_info->transfer_id = __bt_get_transfer_id(transfer_path);
507 if (!transfer_info->device_name)
508 transfer_info->device_name = g_strdup(transfer_info->address);
510 if (transfer_info->type == NULL)
513 transfer_info->path = g_strdup(transfer_path);
516 g_object_unref(transfer_proxy);
517 return BLUETOOTH_ERROR_NONE;
520 g_object_unref(transfer_proxy);
521 return BLUETOOTH_ERROR_INTERNAL;
524 static gboolean __bt_authorize_cb(GDBusMethodInvocation *context,
528 char *device_name = NULL;
529 unsigned char auth_info[5] = {0, };
530 int result = BLUETOOTH_ERROR_NONE;
531 GDBusProxy *transfer_properties_proxy;
532 char * bdaddress = NULL;
535 GVariant *param = NULL;
537 bt_session_info_t *session_info = NULL;
539 BT_DBG(" path [%s] \n", path);
541 transfer_properties_proxy = __bt_get_transfer_properties_proxy(path);
543 retv_if(transfer_properties_proxy == NULL, FALSE);
545 ret = g_dbus_proxy_call_sync(transfer_properties_proxy, "GetAll",
546 g_variant_new("(s)", BT_OBEX_TRANSFER_INTERFACE),
547 G_DBUS_CALL_FLAGS_NONE,
551 BT_ERR("DBus Error : %s", err->message);
556 BT_ERR("g_dbus_proxy_call_sync function return NULL");
559 g_variant_get(ret, "(a{sv})", &iter);
560 g_variant_unref(ret);
562 g_object_unref(transfer_properties_proxy);
566 __bt_free_auth_info(agent_info.auth_info);
568 agent_info.auth_info = g_malloc(sizeof(bt_auth_info_t));
570 memset(agent_info.auth_info, 0, sizeof(bt_auth_info_t));
572 agent_info.auth_info->reply_context = context;
574 agent_info.auth_info->transfer_path = g_strdup(path);
576 #ifdef TIZEN_DPM_ENABLE
577 if (_bt_dpm_get_allow_bluetooth_mode() == DPM_BT_HANDSFREE_ONLY) {
578 /* Free auth info in next function */
579 _bt_obex_server_reject_authorize();
587 while (g_variant_iter_loop(iter, "{sv}", &key, &val)) {
588 if (g_strcmp0(key, "Name") == 0) {
589 agent_info.auth_info->filename = g_variant_dup_string(val, &len);
590 } else if (g_strcmp0(key, "Address") == 0) {
591 bdaddress = g_variant_dup_string(val, &len);
592 } else if (g_strcmp0(key, "Size") == 0) {
593 agent_info.auth_info->file_size = g_variant_get_uint64(val);
596 g_variant_iter_free(iter);
599 __bt_get_remote_device_name_authinfo(bdaddress, &device_name, auth_info);
602 device_name = g_strdup(bdaddress);
604 agent_info.auth_info->address = g_strdup(bdaddress);
605 agent_info.auth_info->device_name = device_name;
606 memcpy(agent_info.auth_info->contact_auth_info, auth_info, 5);
608 session_info = __bt_find_session_by_path((char *)path);
609 if (NULL == session_info) {
610 session_info = g_malloc0(sizeof(bt_session_info_t));
611 session_info->path = g_strdup(path);
612 session_info->address = g_strdup(bdaddress);
613 session_info->authorized = FALSE;
614 session_list = g_slist_append(session_list, session_info);
617 g_object_unref(transfer_properties_proxy);
620 if (agent_info.server_type == BT_CUSTOM_SERVER) {
621 /* No need to send the event */
622 _bt_obex_server_accept_authorize(agent_info.auth_info->filename, FALSE);
626 if (session_info->authorized == FALSE) {
627 _bt_launch_system_popup(BT_AGENT_EVENT_EXCHANGE_REQUEST, device_name,
628 auth_info, NULL, NULL, BT_OBEX_SERVER_AGENT_PATH);
630 param = g_variant_new("(istss)", result,
631 agent_info.auth_info->filename,
632 agent_info.auth_info->file_size,
633 agent_info.auth_info->address,
634 agent_info.auth_info->device_name);
635 _bt_send_event(BT_OPP_SERVER_EVENT,
636 BLUETOOTH_EVENT_OBEX_SERVER_TRANSFER_AUTHORIZE, param);
642 void _bt_obex_transfer_started(const char *transfer_path)
644 bt_transfer_info_t *transfer_info;
645 request_info_t *req_info;
646 GVariant *out_param1 = NULL;
647 GVariant *param = NULL;
648 GVariantBuilder *builder = NULL;
649 int result = BLUETOOTH_ERROR_NONE;
652 BT_DBG("%s", transfer_path);
654 transfer_info = g_malloc0(sizeof(bt_transfer_info_t));
656 if (agent_info.auth_info != NULL
657 && g_strcmp0(transfer_path, agent_info.auth_info->transfer_path) == 0) {
658 transfer_info->filename = g_strdup(agent_info.auth_info->filename);
659 transfer_info->file_size = agent_info.auth_info->file_size;
660 transfer_info->type = g_strdup(TRANSFER_PUT);
661 transfer_info->path = g_strdup(agent_info.auth_info->transfer_path);
662 transfer_info->device_name = g_strdup(agent_info.auth_info->device_name);
663 transfer_info->transfer_id = __bt_get_transfer_id(transfer_path);
664 transfer_info->file_path = agent_info.auth_info->file_path;
665 transfer_info->address = g_strdup(agent_info.auth_info->address);
668 if (__bt_get_transfer_properties(transfer_info, transfer_path) < 0) {
669 BT_ERR("Get Properties failed");
670 __bt_free_transfer_info(transfer_info);
673 agent_info.server_type = BT_FTP_SERVER;
676 if (agent_info.server_type == BT_CUSTOM_SERVER) {
677 if (agent_info.custom_server == NULL) {
678 __bt_free_transfer_info(transfer_info);
679 __bt_free_auth_info(agent_info.auth_info);
680 agent_info.auth_info = NULL;
684 req_info = _bt_get_request_info(agent_info.accept_id);
685 if (req_info == NULL || req_info->context == NULL) {
686 BT_ERR("info is NULL");
690 agent_info.accept_id = 0;
691 result = BLUETOOTH_ERROR_NONE;
692 GArray *g_out_param1 = NULL;
693 g_out_param1 = g_array_new(FALSE, FALSE, sizeof(gchar));
694 if (out_param1 == NULL) {
695 out_param1 = g_variant_new_from_data((const GVariantType *)"ay",
696 g_out_param1->data, g_out_param1->len,
700 g_dbus_method_invocation_return_value(req_info->context,
701 g_variant_new("(iv)", result, out_param1));
702 g_array_free(g_out_param1, TRUE);
703 _bt_delete_request_list(req_info->req_id);
706 transfers = g_slist_append(transfers, transfer_info);
708 BT_DBG("Transfer id %d", transfer_info->transfer_id);
710 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
711 for (i = 0; i < 5; i++) {
712 if (agent_info.auth_info)
713 g_variant_builder_add(builder, "y", agent_info.auth_info->contact_auth_info[i]);
716 param = g_variant_new("(isssstii(ay))", result,
717 transfer_info->device_name,
718 transfer_info->filename,
720 transfer_info->address,
721 transfer_info->file_size,
722 transfer_info->transfer_id,
723 agent_info.server_type,
726 __bt_free_auth_info(agent_info.auth_info);
727 agent_info.auth_info = NULL;
729 g_variant_builder_unref(builder);
731 _bt_send_event(BT_OPP_SERVER_EVENT,
732 BLUETOOTH_EVENT_OBEX_SERVER_TRANSFER_STARTED,
736 void _bt_obex_transfer_progress(const char *transfer_path,
740 bt_transfer_info_t *transfer_info;
741 int current_progress = 0;
742 int previous_progress;
743 GVariant *param = NULL;
744 int result = BLUETOOTH_ERROR_NONE;
746 transfer_info = __bt_find_transfer_by_path(transfer_path);
747 ret_if(transfer_info == NULL);
749 current_progress = (int)(((gdouble)transferred /
750 (gdouble)transfer_info->file_size) * 100);
752 previous_progress = (int)(((gdouble)transfer_info->progress /
753 (gdouble)transfer_info->file_size) * 100);
755 if (current_progress == previous_progress) {
756 BT_DBG("Same Percentage Value: Do not emit Signal");
760 transfer_info->progress = transferred;
761 param = g_variant_new("(isssstiii)", result,
762 transfer_info->filename,
764 transfer_info->device_name,
765 transfer_info->address,
766 transfer_info->file_size,
767 transfer_info->transfer_id,
769 agent_info.server_type);
770 _bt_send_event(BT_OPP_SERVER_EVENT,
771 BLUETOOTH_EVENT_OBEX_SERVER_TRANSFER_PROGRESS,
776 void _bt_obex_transfer_completed(const char *transfer_path, gboolean success)
778 bt_transfer_info_t *transfer_info;
779 GVariantBuilder *builder = NULL;
780 GVariant *param = NULL;
783 BT_DBG("Transfer [%s] Success [%d] \n", transfer_path, success);
785 result = (success == TRUE) ? BLUETOOTH_ERROR_NONE
786 : BLUETOOTH_ERROR_CANCEL;
788 transfer_info = __bt_find_transfer_by_path(transfer_path);
790 if (transfer_info == NULL) {
791 BT_DBG("Very small files receiving case, did not get Active status from obexd");
792 if (agent_info.auth_info == NULL ||
793 g_strcmp0(transfer_path,
794 agent_info.auth_info->transfer_path) != 0) {
795 BT_ERR("auth_info is NULL, returning");
799 transfer_info = g_new0(bt_transfer_info_t, 1);
801 transfer_info->filename = g_strdup(agent_info.auth_info->filename);
802 transfer_info->file_size = agent_info.auth_info->file_size;
803 transfer_info->type = g_strdup(TRANSFER_PUT);
804 transfer_info->path = g_strdup(agent_info.auth_info->transfer_path);
805 transfer_info->device_name = g_strdup(agent_info.auth_info->device_name);
806 transfer_info->transfer_id = __bt_get_transfer_id(transfer_path);
807 transfer_info->file_path = agent_info.auth_info->file_path;
808 transfer_info->address = g_strdup(agent_info.auth_info->address);
810 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
811 for (i = 0; i < 5; i++)
812 g_variant_builder_add(builder, "y", agent_info.auth_info->contact_auth_info[i]);
814 param = g_variant_new("(isssstii(ay))", result,
815 transfer_info->filename,
817 transfer_info->device_name,
818 transfer_info->address,
819 transfer_info->file_size,
820 transfer_info->transfer_id,
821 agent_info.server_type,
823 _bt_send_event(BT_OPP_SERVER_EVENT,
824 BLUETOOTH_EVENT_OBEX_SERVER_TRANSFER_STARTED,
826 g_variant_builder_unref(builder);
828 param = g_variant_new("(issssstii)", result,
829 transfer_info->filename,
831 transfer_info->device_name,
832 transfer_info->file_path,
833 transfer_info->address,
834 transfer_info->file_size,
835 transfer_info->transfer_id,
836 agent_info.server_type);
837 _bt_send_event(BT_OPP_SERVER_EVENT,
838 BLUETOOTH_EVENT_OBEX_SERVER_TRANSFER_COMPLETED,
840 transfers = g_slist_remove(transfers, transfer_info);
841 __bt_free_transfer_info(transfer_info);
844 void _bt_obex_transfer_connected(const char *obj_path)
848 int result = BLUETOOTH_ERROR_NONE;
849 GVariant *param = NULL;
850 bt_transfer_info_t *transfer_info = NULL;
852 transfer_info = g_new0(bt_transfer_info_t, 1);
853 __bt_get_transfer_properties(transfer_info, obj_path);
854 INFO_SECURE("Address[%s] Name[%s] TransferID[%d] ", transfer_info->address,
855 transfer_info->device_name, transfer_info->transfer_id);
857 param = g_variant_new("(issi)", result, transfer_info->address,
858 transfer_info->device_name, transfer_info->transfer_id);
860 _bt_send_event(BT_OPP_SERVER_EVENT,
861 BLUETOOTH_EVENT_OBEX_SERVER_TRANSFER_CONNECTED,
864 __bt_free_transfer_info(transfer_info);
868 void _bt_obex_transfer_disconnected(char * obj_path)
872 int result = BLUETOOTH_ERROR_NONE;
873 GVariant *param = NULL;
874 bt_session_info_t *session = NULL;
875 int transfer_id = -1;
877 session = __bt_find_session_by_path(obj_path);
878 ret_if(session == NULL);
880 transfer_id = __bt_get_transfer_id(obj_path);
881 DBG_SECURE("transfer_id: [%d]", transfer_id);
883 DBG_SECURE("%s", session->address);
884 param = g_variant_new("(isi)", result, session->address, transfer_id);
885 _bt_send_event(BT_OPP_SERVER_EVENT,
886 BLUETOOTH_EVENT_OBEX_SERVER_TRANSFER_DISCONNECTED,
888 session_list = g_slist_remove(session_list, session);
889 g_free(session->address);
890 g_free(session->path);
895 int _bt_register_obex_server(void)
897 GDBusConnection *g_conn;
898 GDBusProxy *manager_proxy;
899 GVariant *result = NULL;
900 GError *g_error = NULL;
902 /* Get the session bus. */
903 g_conn = _bt_gdbus_get_session_gconn();
904 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
906 _bt_obex_agent_new(BT_OBEX_SERVER_AGENT_PATH);
908 _bt_obex_setup(BT_OBEX_SERVER_AGENT_PATH);
910 _bt_obex_set_authorize_cb(BT_OBEX_SERVER_AGENT_PATH,
911 __bt_authorize_cb, NULL);
913 manager_proxy = g_dbus_proxy_new_sync(g_conn, G_DBUS_PROXY_FLAGS_NONE,
914 NULL, BT_OBEX_SERVICE,
919 if (manager_proxy == NULL) {
920 return BLUETOOTH_ERROR_INTERNAL;
923 result = g_dbus_proxy_call_sync(manager_proxy, "RegisterAgent",
924 g_variant_new("(o)", BT_OBEX_SERVER_AGENT_PATH),
925 G_DBUS_CALL_FLAGS_NONE,
929 if (g_error != NULL) {
930 BT_ERR("Agent registration failed: %s\n", g_error->message);
931 g_object_unref(manager_proxy);
932 g_error_free(g_error);
933 return BLUETOOTH_ERROR_INTERNAL;
937 g_variant_unref(result);
939 agent_info.proxy = manager_proxy;
941 return BLUETOOTH_ERROR_NONE;
944 int _bt_unregister_obex_server(void)
946 GVariant *result = NULL;
947 GError *g_error = NULL;
949 retv_if(agent_info.proxy == NULL,
950 BLUETOOTH_ERROR_INTERNAL);
952 result = g_dbus_proxy_call_sync(agent_info.proxy, "UnregisterAgent",
953 g_variant_new("(o)", BT_OBEX_SERVER_AGENT_PATH),
954 G_DBUS_CALL_FLAGS_NONE,
957 if (g_error != NULL) {
958 BT_ERR("Agent unregistration failed: %s", g_error->message);
959 g_error_free(g_error);
963 g_variant_unref(result);
965 _bt_obex_agent_destroy(BT_OBEX_SERVER_AGENT_PATH);
966 g_object_unref(agent_info.proxy);
967 agent_info.proxy = NULL;
969 return BLUETOOTH_ERROR_NONE;
972 gboolean __bt_check_folder_path(const char *dest_path)
976 retv_if(dest_path == NULL, FALSE);
978 dp = opendir(dest_path);
981 BT_ERR("The directory does not exist");
990 char *__bt_transfer_folder_path(char *dest_path)
992 char *dst_path = (char *)g_malloc0(BT_OBEX_PATH_MAX_LENGTH);
993 if (g_str_has_prefix(dest_path, BT_OBEX_PATH_PREFIX)) {
994 snprintf(dst_path, BT_OBEX_PATH_MAX_LENGTH, BT_OBEX_DEFAULT_PATH"%s", dest_path + strlen(BT_OBEX_PATH_PREFIX));
996 snprintf(dst_path, BT_OBEX_PATH_MAX_LENGTH, "%s", dest_path);
999 BT_INFO("obex transfed path : %s", dst_path);
1003 int _bt_obex_server_allocate(char *sender, const char *dest_path, int app_pid, gboolean is_native)
1008 dst_path = __bt_transfer_folder_path((char *)dest_path);
1010 if (__bt_check_folder_path(dst_path) == FALSE) {
1012 return BLUETOOTH_ERROR_INVALID_PARAM;
1015 if (is_native == TRUE) {
1016 if (agent_info.native_server) {
1017 BT_ERR("obex native server busy");
1019 return BLUETOOTH_ERROR_DEVICE_BUSY;
1022 /* Force to change the control to native */
1023 agent_info.native_server = g_malloc0(sizeof(bt_server_info_t));
1024 agent_info.native_server->dest_path = g_strdup(dst_path);
1025 agent_info.native_server->sender = g_strdup(sender);
1026 agent_info.native_server->app_pid = app_pid;
1027 agent_info.server_type = BT_NATIVE_SERVER;
1028 _bt_unregister_osp_server_in_agent(BT_OBEX_SERVER, NULL);
1030 if (agent_info.custom_server) {
1031 BT_ERR("obex custom server busy");
1033 return BLUETOOTH_ERROR_DEVICE_BUSY;
1036 /* Force to change the control to custom */
1037 agent_info.custom_server = g_malloc0(sizeof(bt_server_info_t));
1038 agent_info.custom_server->dest_path = g_strdup(dst_path);
1039 agent_info.custom_server->sender = g_strdup(sender);
1040 agent_info.custom_server->app_pid = app_pid;
1041 agent_info.server_type = BT_CUSTOM_SERVER;
1042 _bt_register_osp_server_in_agent(BT_OBEX_SERVER, NULL, NULL, -1);
1047 return BLUETOOTH_ERROR_NONE;
1050 int _bt_obex_server_deallocate(int app_pid, gboolean is_native)
1052 if (is_native == TRUE) {
1053 retv_if(agent_info.native_server == NULL,
1054 BLUETOOTH_ERROR_AGENT_DOES_NOT_EXIST);
1056 retv_if(agent_info.native_server->app_pid != app_pid,
1057 BLUETOOTH_ERROR_ACCESS_DENIED);
1059 __bt_free_server_info(agent_info.native_server);
1060 agent_info.native_server = NULL;
1062 /* Change the control to custom */
1063 if (agent_info.custom_server) {
1064 agent_info.server_type = BT_CUSTOM_SERVER;
1065 _bt_register_osp_server_in_agent(BT_OBEX_SERVER,
1069 retv_if(agent_info.custom_server == NULL,
1070 BLUETOOTH_ERROR_AGENT_DOES_NOT_EXIST);
1072 retv_if(agent_info.custom_server->app_pid != app_pid,
1073 BLUETOOTH_ERROR_ACCESS_DENIED);
1075 __bt_free_server_info(agent_info.custom_server);
1076 agent_info.custom_server = NULL;
1078 _bt_unregister_osp_server_in_agent(BT_OBEX_SERVER, NULL);
1080 /* Change the control to native */
1081 if (agent_info.native_server)
1082 agent_info.server_type = BT_NATIVE_SERVER;
1085 return BLUETOOTH_ERROR_NONE;
1088 int _bt_obex_server_accept_authorize(const char *filename, gboolean is_native)
1090 char file_path[BT_FILE_PATH_MAX] = { 0 };
1091 bt_server_info_t *server_info;
1093 BT_CHECK_PARAMETER(filename, return);
1095 retv_if(agent_info.auth_info == NULL, BLUETOOTH_ERROR_INTERNAL);
1097 retv_if(agent_info.auth_info->reply_context == NULL,
1098 BLUETOOTH_ERROR_INTERNAL);
1100 if (is_native == TRUE)
1101 server_info = agent_info.native_server;
1103 server_info = agent_info.custom_server;
1105 retv_if(server_info == NULL, BLUETOOTH_ERROR_INTERNAL);
1107 if (server_info->dest_path != NULL)
1108 snprintf(file_path, sizeof(file_path), "%s/%s",
1109 server_info->dest_path, filename);
1111 snprintf(file_path, sizeof(file_path), "%s", filename);
1113 g_dbus_method_invocation_return_value(agent_info.auth_info->reply_context,
1114 g_variant_new("(s)", &file_path));
1115 agent_info.auth_info->reply_context = NULL;
1116 agent_info.auth_info->file_path = g_strdup(file_path);
1117 g_free(agent_info.auth_info->filename);
1118 agent_info.auth_info->filename = g_strdup(filename);
1120 return BLUETOOTH_ERROR_NONE;
1123 void _bt_obex_server_reply_accept(void)
1125 GVariant *param = NULL;
1126 bt_session_info_t *session_info = NULL;
1127 int result = BLUETOOTH_ERROR_NONE;
1128 param = g_variant_new("(istss)", result,
1129 agent_info.auth_info->filename,
1130 agent_info.auth_info->file_size,
1131 agent_info.auth_info->address,
1132 agent_info.auth_info->device_name);
1133 BT_INFO("Send Obex Authorize");
1134 _bt_send_event(BT_OPP_SERVER_EVENT, BLUETOOTH_EVENT_OBEX_SERVER_TRANSFER_AUTHORIZE, param);
1136 session_info = __bt_find_session_by_path(agent_info.auth_info->transfer_path);
1138 if (NULL == session_info)
1139 BT_ERR("Couldn't get the session info from the list");
1141 session_info->authorized = TRUE;
1144 int _bt_obex_server_reject_authorize(void)
1148 retv_if(agent_info.auth_info->reply_context == NULL,
1149 BLUETOOTH_ERROR_INTERNAL);
1151 g_error = g_error_new(__bt_obex_error_quark(),
1152 BT_OBEX_AGENT_ERROR_CANCEL,
1155 g_dbus_method_invocation_return_gerror(agent_info.auth_info->reply_context,
1157 g_error_free(g_error);
1159 __bt_free_auth_info(agent_info.auth_info);
1160 agent_info.auth_info = NULL;
1162 return BLUETOOTH_ERROR_NONE;
1165 int _bt_obex_server_set_destination_path(const char *dest_path,
1168 bt_server_info_t *server_info;
1169 BT_CHECK_PARAMETER(dest_path, return);
1172 dst_path = __bt_transfer_folder_path((char *)dest_path);
1176 dp = opendir(dst_path);
1179 BT_ERR("The directory does not exist");
1181 return BLUETOOTH_ERROR_INVALID_PARAM;
1186 if (is_native == TRUE)
1187 server_info = agent_info.native_server;
1189 server_info = agent_info.custom_server;
1192 BT_ERR("obex server info is NULL");
1194 return BLUETOOTH_ERROR_AGENT_DOES_NOT_EXIST;
1197 g_free(server_info->dest_path);
1198 server_info->dest_path = g_strdup(dst_path);
1201 return BLUETOOTH_ERROR_NONE;
1204 int _bt_obex_server_set_root(const char *root)
1206 GVariant *result = NULL;
1207 GError *g_error = NULL;
1208 GVariant *folder = NULL;
1209 char *string = "Root";
1212 BT_CHECK_PARAMETER(root, return);
1215 dst_root = __bt_transfer_folder_path((char *)root);
1217 if (!agent_info.proxy) {
1218 BT_ERR("obex agent_info proxy error");
1220 return BLUETOOTH_ERROR_INTERNAL;
1223 dp = opendir(dst_root);
1226 BT_ERR("The directory does not exist");
1228 return BLUETOOTH_ERROR_INVALID_PARAM;
1233 folder = g_variant_new_string(dst_root);
1234 result = g_dbus_proxy_call_sync(agent_info.proxy, "SetProperty",
1235 g_variant_new("(sv)", string, folder),
1236 G_DBUS_CALL_FLAGS_NONE,
1241 BT_ERR("SetProperty Fail: %s", g_error->message);
1242 g_error_free(g_error);
1244 return BLUETOOTH_ERROR_INTERNAL;
1248 g_variant_unref(result);
1251 return BLUETOOTH_ERROR_NONE;
1254 int _bt_obex_server_cancel_transfer(int transfer_id)
1256 bt_transfer_info_t *transfer = NULL;
1258 GVariant *result = NULL;
1261 transfer = __bt_find_transfer_by_id(transfer_id);
1263 retv_if(transfer == NULL, BLUETOOTH_ERROR_NOT_FOUND);
1264 proxy = __bt_get_transfer_proxy(transfer->path);
1266 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1268 result = g_dbus_proxy_call_sync(proxy, "Cancel", NULL,
1269 G_DBUS_CALL_FLAGS_NONE,
1270 DBUS_TIMEOUT, NULL, &err);
1272 BT_ERR("Dbus Err: %s", err->message);
1273 g_clear_error(&err);
1276 g_object_unref(proxy);
1279 g_variant_unref(result);
1281 return BLUETOOTH_ERROR_NONE;
1284 int _bt_obex_server_cancel_all_transfers(void)
1287 bt_transfer_info_t *transfer;
1289 for (l = transfers; l != NULL; l = l->next) {
1292 if (transfer == NULL)
1295 _bt_obex_server_cancel_transfer(transfer->transfer_id);
1298 return BLUETOOTH_ERROR_NONE;
1301 int _bt_obex_server_is_activated(gboolean *activated)
1303 BT_CHECK_PARAMETER(activated, return);
1305 if (agent_info.custom_server) {
1311 return BLUETOOTH_ERROR_NONE;
1314 int _bt_obex_server_check_allocation(gboolean *allocation)
1316 BT_CHECK_PARAMETER(allocation, return);
1318 if (agent_info.native_server || agent_info.custom_server) {
1321 *allocation = FALSE;
1324 return BLUETOOTH_ERROR_NONE;
1327 int _bt_obex_server_check_termination(char *sender)
1329 BT_CHECK_PARAMETER(sender, return);
1331 if (agent_info.native_server) {
1332 if (g_strcmp0(sender, agent_info.native_server->sender) == 0) {
1333 _bt_obex_server_deallocate(agent_info.native_server->app_pid,
1338 if (agent_info.custom_server) {
1339 if (g_strcmp0(sender, agent_info.custom_server->sender) == 0) {
1340 _bt_obex_server_deallocate(agent_info.custom_server->app_pid,
1345 return BLUETOOTH_ERROR_NONE;
1348 int _bt_obex_server_is_receiving(gboolean *receiving)
1350 BT_CHECK_PARAMETER(receiving, return);
1352 if (transfers == NULL || g_slist_length(transfers) == 0) {
1358 return BLUETOOTH_ERROR_NONE;
1361 gboolean __bt_obex_server_accept_timeout_cb(gpointer user_data)
1363 request_info_t *req_info;
1364 GVariant *out_param1 = NULL;
1365 int result = BLUETOOTH_ERROR_TIMEOUT;
1367 /* Already reply in _bt_obex_transfer_started */
1368 retv_if(agent_info.accept_id == 0, FALSE);
1370 req_info = _bt_get_request_info(agent_info.accept_id);
1371 if (req_info == NULL || req_info->context == NULL) {
1372 BT_ERR("info is NULL");
1376 agent_info.accept_id = 0;
1377 GArray *g_out_param1 = NULL;
1378 g_out_param1 = g_array_new(FALSE, FALSE, sizeof(gchar));
1379 if (out_param1 == NULL) {
1380 out_param1 = g_variant_new_from_data((const GVariantType *)"ay",
1381 g_out_param1->data, g_out_param1->len,
1385 g_dbus_method_invocation_return_value(req_info->context,
1386 g_variant_new("(iv)", result, out_param1));
1387 g_array_free(g_out_param1, TRUE);
1388 _bt_delete_request_list(req_info->req_id);
1393 /* To support the BOT */
1394 int _bt_obex_server_accept_connection(int request_id)
1396 if (!_bt_agent_reply_authorize(TRUE))
1397 return BLUETOOTH_ERROR_INTERNAL;
1399 agent_info.accept_id = request_id;
1401 g_timeout_add(BT_SERVER_ACCEPT_TIMEOUT,
1402 (GSourceFunc)__bt_obex_server_accept_timeout_cb,
1405 return BLUETOOTH_ERROR_NONE;
1408 /* To support the BOT */
1409 int _bt_obex_server_reject_connection(void)
1411 if (!_bt_agent_reply_authorize(FALSE))
1412 return BLUETOOTH_ERROR_INTERNAL;
1414 return BLUETOOTH_ERROR_NONE;
1417 int _bt_opp_get_server_progress(int transfer_id, guint8 *progress)
1419 bt_transfer_info_t *requested_transfer = NULL;
1420 requested_transfer = __bt_find_transfer_by_id(transfer_id);
1421 if (requested_transfer == NULL) {
1422 BT_ERR("No Matching Inbound transfer");
1423 return BLUETOOTH_ERROR_NOT_FOUND;
1426 *progress = (int)(((double)requested_transfer->progress /
1427 requested_transfer->file_size) * 100);
1429 BT_DBG("Percentage: %d", *progress);
1430 return BLUETOOTH_ERROR_NONE;