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_FEATURE_BT_DPM
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;
250 const gchar *name = NULL;
251 gchar *dev_name = NULL;
253 GVariant *result = NULL;
255 GDBusProxy *device_proxy;
256 GDBusConnection *conn;
258 retv_if(bdaddress == NULL, NULL);
260 device_path = _bt_get_device_object_path((char *)bdaddress);
261 retv_if(device_path == NULL, NULL);
263 conn = _bt_gdbus_get_system_gconn();
264 retv_if(conn == NULL, NULL);
265 BT_INFO("Device_path %s", device_path);
266 device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
269 BT_PROPERTIES_INTERFACE,
273 retv_if(device_proxy == NULL, NULL);
275 result = g_dbus_proxy_call_sync(device_proxy, "Get",
276 g_variant_new("(ss)", BT_DEVICE_INTERFACE, "Alias"),
277 G_DBUS_CALL_FLAGS_NONE, DBUS_TIMEOUT, NULL, &err);
279 BT_ERR("DBus Error : %s", err->message);
283 g_variant_get(result, "(v)", &value);
284 name = g_variant_get_string(value, &name_len);
285 INFO_SECURE("Alias Name [%s]", name);
287 dev_name = g_strdup(name);
288 g_variant_unref(value);
289 g_variant_unref(result);
293 result = g_dbus_proxy_call_sync(device_proxy, "Get",
294 g_variant_new("(ss)", BT_DEVICE_INTERFACE, "Name"),
295 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err);
297 ERR("DBus Error : %s", err->message);
301 g_variant_get(result, "(v)", &value);
302 name = g_variant_get_string(value, &name_len);
303 INFO_SECURE("Name = %s", name);
305 dev_name = g_strdup(name);
306 g_variant_unref(value);
307 g_variant_unref(result);
311 g_object_unref(device_proxy);
315 static void __bt_get_remote_device_name_authinfo(const char *bdaddress,
316 char **device_name, unsigned char *auth_info)
318 char *device_path = NULL;
320 gboolean is_alias_set;
322 GVariant *result = NULL;
324 GDBusProxy *device_proxy;
325 GDBusConnection *conn;
327 ret_if(bdaddress == NULL);
329 device_path = _bt_get_device_object_path((char *)bdaddress);
330 ret_if(device_path == NULL);
332 conn = _bt_gdbus_get_system_gconn();
333 ret_if(conn == NULL);
334 BT_INFO("Device_path %s", device_path);
335 device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
338 BT_PROPERTIES_INTERFACE,
342 ret_if(device_proxy == NULL);
344 result = g_dbus_proxy_call_sync(device_proxy, "GetAll",
345 g_variant_new("(s)", BT_DEVICE_INTERFACE),
346 G_DBUS_CALL_FLAGS_NONE,
350 BT_ERR("DBus Error : %s", err->message);
354 if (result == NULL) {
355 BT_ERR("g_dbus_proxy_call_sync function return NULL");
358 g_variant_get(result, "(@a{sv})", &value);
361 GVariant *temp_value = g_variant_lookup_value(value, "Alias",
362 G_VARIANT_TYPE_STRING);
363 g_variant_get(temp_value, "s", &name);
365 g_variant_unref(temp_value);
368 DBG_SECURE("Alias Name [%s]", name);
370 temp_value = g_variant_lookup_value(value, "Name", G_VARIANT_TYPE_STRING);
371 g_variant_get(temp_value, "s", &name);
373 g_variant_unref(temp_value);
374 DBG_SECURE("Name = %s", name);
376 temp_value = g_variant_lookup_value(value, "IsAliasSet", G_VARIANT_TYPE_BOOLEAN);
378 is_alias_set = g_variant_get_boolean(temp_value);
379 g_variant_unref(temp_value);
381 is_alias_set = FALSE;
384 if (is_alias_set == FALSE)
385 __bt_get_auth_info(value, (char *)auth_info);
387 g_variant_unref(result);
388 g_object_unref(device_proxy);
390 *device_name = g_strdup(name);
395 static int __bt_get_transfer_id(const char *path)
401 tmp = strrchr(path, 'r') + 1;
402 retv_if(tmp == NULL, -1);
407 static GDBusProxy *__bt_get_transfer_proxy(const char *transfer_path)
409 GDBusConnection *conn;
413 conn = _bt_gdbus_get_system_gconn();
414 retv_if(conn == NULL, NULL);
416 proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
417 NULL, BT_OBEX_SERVICE_NAME,
419 BT_OBEX_TRANSFER_INTERFACE,
422 if (proxy == NULL && err) {
423 BT_ERR("Error : %s", err->message);
431 static GDBusProxy *__bt_get_transfer_properties_proxy(const char *transfer_path)
433 GDBusConnection *conn;
436 conn = _bt_gdbus_get_system_gconn();
437 retv_if(conn == NULL, NULL);
439 proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
440 NULL, BT_OBEX_SERVICE_NAME,
442 BT_PROPERTIES_INTERFACE,
444 if (proxy == NULL && err) {
445 BT_ERR("Error : %s", err->message);
452 static int __bt_get_transfer_properties(bt_transfer_info_t *transfer_info,
453 const char *transfer_path)
455 GDBusProxy *transfer_proxy;
456 GVariant *result = NULL;
458 GVariantIter *iter = NULL;
459 BT_CHECK_PARAMETER(transfer_info, return);
460 BT_CHECK_PARAMETER(transfer_path, return);
462 transfer_proxy = __bt_get_transfer_properties_proxy(transfer_path);
464 retv_if(transfer_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
466 result = g_dbus_proxy_call_sync(transfer_proxy, "GetAll",
467 g_variant_new("(s)", BT_OBEX_TRANSFER_INTERFACE),
468 G_DBUS_CALL_FLAGS_NONE,
473 BT_ERR("DBus Error : %s", err->message);
477 if (result == NULL) {
478 BT_ERR("g_dbus_proxy_call_sync function return NULL");
482 g_variant_get(result, "(a{sv})", &iter);
483 g_variant_unref(result);
488 while (g_variant_iter_loop(iter, "{sv}", &key, &val)) {
489 if (g_strcmp0(key, "Operation") == 0) {
490 transfer_info->type = g_variant_dup_string(val, &len);
491 } else if (g_strcmp0(key, "Name") == 0) {
492 transfer_info->filename = g_variant_dup_string(val, &len);
493 } else if (g_strcmp0(key, "Size") == 0) {
494 transfer_info->file_size = g_variant_get_uint64(val);
495 } else if (g_strcmp0(key, "Address") == 0) {
496 transfer_info->address = g_variant_dup_string(val, &len);
497 BT_INFO("addressss %s", transfer_info->address);
498 } else if (g_strcmp0(key, "Filename") == 0) {
499 transfer_info->file_path = g_variant_dup_string(val, &len);
500 if (!transfer_info->file_path)
501 transfer_info->file_path = g_strdup(transfer_info->filename);
504 g_variant_iter_free(iter);
506 if (transfer_info->address == NULL)
508 transfer_info->device_name = __bt_get_remote_device_name(transfer_info->address);
509 transfer_info->transfer_id = __bt_get_transfer_id(transfer_path);
510 if (!transfer_info->device_name)
511 transfer_info->device_name = g_strdup(transfer_info->address);
513 if (transfer_info->type == NULL)
516 transfer_info->path = g_strdup(transfer_path);
519 g_object_unref(transfer_proxy);
520 return BLUETOOTH_ERROR_NONE;
523 g_object_unref(transfer_proxy);
524 return BLUETOOTH_ERROR_INTERNAL;
527 static gboolean __bt_authorize_cb(GDBusMethodInvocation *context,
531 char *device_name = NULL;
532 unsigned char auth_info[5] = {0, };
533 int result = BLUETOOTH_ERROR_NONE;
534 GDBusProxy *transfer_properties_proxy;
535 char * bdaddress = NULL;
538 GVariant *param = NULL;
540 bt_session_info_t *session_info = NULL;
541 #ifdef TIZEN_FEATURE_BT_DPM
542 int value = DPM_BT_ERROR;
545 BT_DBG(" path [%s] \n", path);
547 transfer_properties_proxy = __bt_get_transfer_properties_proxy(path);
549 retv_if(transfer_properties_proxy == NULL, FALSE);
551 ret = g_dbus_proxy_call_sync(transfer_properties_proxy, "GetAll",
552 g_variant_new("(s)", BT_OBEX_TRANSFER_INTERFACE),
553 G_DBUS_CALL_FLAGS_NONE,
557 BT_ERR("DBus Error : %s", err->message);
562 BT_ERR("g_dbus_proxy_call_sync function return NULL");
565 g_variant_get(ret, "(a{sv})", &iter);
566 g_variant_unref(ret);
568 g_object_unref(transfer_properties_proxy);
572 __bt_free_auth_info(agent_info.auth_info);
574 agent_info.auth_info = g_malloc(sizeof(bt_auth_info_t));
576 memset(agent_info.auth_info, 0, sizeof(bt_auth_info_t));
578 agent_info.auth_info->reply_context = context;
580 agent_info.auth_info->transfer_path = g_strdup(path);
582 #ifdef TIZEN_FEATURE_BT_DPM
583 _bt_dpm_get_allow_bluetooth_mode(&value);
584 if (value == DPM_BT_HANDSFREE_ONLY) {
585 /* Free auth info in next function */
586 _bt_obex_server_reject_authorize();
594 while (g_variant_iter_loop(iter, "{sv}", &key, &val)) {
595 if (g_strcmp0(key, "Name") == 0)
596 agent_info.auth_info->filename = g_variant_dup_string(val, &len);
597 else if (g_strcmp0(key, "Address") == 0)
598 bdaddress = g_variant_dup_string(val, &len);
599 else if (g_strcmp0(key, "Size") == 0)
600 agent_info.auth_info->file_size = g_variant_get_uint64(val);
602 g_variant_iter_free(iter);
605 __bt_get_remote_device_name_authinfo(bdaddress, &device_name, auth_info);
608 device_name = g_strdup(bdaddress);
610 agent_info.auth_info->address = g_strdup(bdaddress);
611 agent_info.auth_info->device_name = device_name;
612 memcpy(agent_info.auth_info->contact_auth_info, auth_info, 5);
614 session_info = __bt_find_session_by_path((char *)path);
615 if (NULL == session_info) {
616 session_info = g_malloc0(sizeof(bt_session_info_t));
617 session_info->path = g_strdup(path);
618 session_info->address = g_strdup(bdaddress);
619 session_info->authorized = FALSE;
620 session_list = g_slist_append(session_list, session_info);
623 g_object_unref(transfer_properties_proxy);
626 if (agent_info.server_type == BT_CUSTOM_SERVER) {
627 /* No need to send the event */
628 _bt_obex_server_accept_authorize(agent_info.auth_info->filename, FALSE);
632 if (session_info->authorized == FALSE) {
633 if (headed_plugin_info->plugin_headed_enabled)
634 headed_plugin_info->headed_plugin->bt_launch_system_popup(BT_AGENT_EVENT_EXCHANGE_REQUEST, device_name,
635 auth_info, NULL, NULL, BT_OBEX_SERVER_AGENT_PATH);
637 param = g_variant_new("(istss)", result,
638 agent_info.auth_info->filename,
639 agent_info.auth_info->file_size,
640 agent_info.auth_info->address,
641 agent_info.auth_info->device_name);
642 _bt_send_event(BT_OPP_SERVER_EVENT,
643 BLUETOOTH_EVENT_OBEX_SERVER_TRANSFER_AUTHORIZE, param);
649 void _bt_obex_transfer_started(const char *transfer_path)
651 bt_transfer_info_t *transfer_info;
652 request_info_t *req_info;
653 GVariant *out_param1 = NULL;
654 GVariant *param = NULL;
655 GVariantBuilder *builder = NULL;
656 int result = BLUETOOTH_ERROR_NONE;
659 BT_DBG("%s", transfer_path);
661 transfer_info = g_malloc0(sizeof(bt_transfer_info_t));
663 if (agent_info.auth_info != NULL
664 && g_strcmp0(transfer_path, agent_info.auth_info->transfer_path) == 0) {
665 transfer_info->filename = g_strdup(agent_info.auth_info->filename);
666 transfer_info->file_size = agent_info.auth_info->file_size;
667 transfer_info->type = g_strdup(TRANSFER_PUT);
668 transfer_info->path = g_strdup(agent_info.auth_info->transfer_path);
669 transfer_info->device_name = g_strdup(agent_info.auth_info->device_name);
670 transfer_info->transfer_id = __bt_get_transfer_id(transfer_path);
671 transfer_info->file_path = agent_info.auth_info->file_path;
672 transfer_info->address = g_strdup(agent_info.auth_info->address);
675 if (__bt_get_transfer_properties(transfer_info, transfer_path) < 0) {
676 BT_ERR("Get Properties failed");
677 __bt_free_transfer_info(transfer_info);
680 agent_info.server_type = BT_FTP_SERVER;
683 if (agent_info.server_type == BT_CUSTOM_SERVER) {
684 if (agent_info.custom_server == NULL) {
685 __bt_free_transfer_info(transfer_info);
686 __bt_free_auth_info(agent_info.auth_info);
687 agent_info.auth_info = NULL;
691 req_info = _bt_get_request_info(agent_info.accept_id);
692 if (req_info == NULL || req_info->context == NULL) {
693 BT_ERR("info is NULL");
697 agent_info.accept_id = 0;
698 result = BLUETOOTH_ERROR_NONE;
699 GArray *g_out_param1 = NULL;
700 g_out_param1 = g_array_new(FALSE, FALSE, sizeof(gchar));
701 if (out_param1 == NULL) {
702 out_param1 = g_variant_new_from_data((const GVariantType *)"ay",
703 g_out_param1->data, g_out_param1->len,
707 g_dbus_method_invocation_return_value(req_info->context,
708 g_variant_new("(iv)", result, out_param1));
709 g_array_free(g_out_param1, TRUE);
710 _bt_delete_request_list(req_info->req_id);
713 transfers = g_slist_append(transfers, transfer_info);
715 BT_DBG("Transfer id %d", transfer_info->transfer_id);
717 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
718 for (i = 0; i < 5; i++) {
719 if (agent_info.auth_info)
720 g_variant_builder_add(builder, "y", agent_info.auth_info->contact_auth_info[i]);
723 param = g_variant_new("(isssstii(ay))", result,
724 transfer_info->device_name,
725 transfer_info->filename,
727 transfer_info->address,
728 transfer_info->file_size,
729 transfer_info->transfer_id,
730 agent_info.server_type,
733 __bt_free_auth_info(agent_info.auth_info);
734 agent_info.auth_info = NULL;
736 g_variant_builder_unref(builder);
738 _bt_send_event(BT_OPP_SERVER_EVENT,
739 BLUETOOTH_EVENT_OBEX_SERVER_TRANSFER_STARTED,
743 void _bt_obex_transfer_progress(const char *transfer_path,
747 bt_transfer_info_t *transfer_info;
748 int current_progress = 0;
749 int previous_progress;
750 GVariant *param = NULL;
751 int result = BLUETOOTH_ERROR_NONE;
753 transfer_info = __bt_find_transfer_by_path(transfer_path);
754 ret_if(transfer_info == NULL);
756 current_progress = (int)(((gdouble)transferred /
757 (gdouble)transfer_info->file_size) * 100);
759 previous_progress = (int)(((gdouble)transfer_info->progress /
760 (gdouble)transfer_info->file_size) * 100);
762 if (current_progress == previous_progress) {
763 BT_DBG("Same Percentage Value: Do not emit Signal");
767 transfer_info->progress = transferred;
768 param = g_variant_new("(isssstiii)", result,
769 transfer_info->filename,
771 transfer_info->device_name,
772 transfer_info->address,
773 transfer_info->file_size,
774 transfer_info->transfer_id,
776 agent_info.server_type);
777 _bt_send_event(BT_OPP_SERVER_EVENT,
778 BLUETOOTH_EVENT_OBEX_SERVER_TRANSFER_PROGRESS,
783 void _bt_obex_transfer_completed(const char *transfer_path, gboolean success)
785 bt_transfer_info_t *transfer_info;
786 GVariantBuilder *builder = NULL;
787 GVariant *param = NULL;
790 BT_DBG("Transfer [%s] Success [%d] \n", transfer_path, success);
792 result = (success == TRUE) ? BLUETOOTH_ERROR_NONE
793 : BLUETOOTH_ERROR_CANCEL;
795 transfer_info = __bt_find_transfer_by_path(transfer_path);
797 if (transfer_info == NULL) {
798 BT_DBG("Very small files receiving case, did not get Active status from obexd");
799 if (agent_info.auth_info == NULL ||
800 g_strcmp0(transfer_path,
801 agent_info.auth_info->transfer_path) != 0) {
802 BT_ERR("auth_info is NULL, returning");
806 transfer_info = g_new0(bt_transfer_info_t, 1);
808 transfer_info->filename = g_strdup(agent_info.auth_info->filename);
809 transfer_info->file_size = agent_info.auth_info->file_size;
810 transfer_info->type = g_strdup(TRANSFER_PUT);
811 transfer_info->path = g_strdup(agent_info.auth_info->transfer_path);
812 transfer_info->device_name = g_strdup(agent_info.auth_info->device_name);
813 transfer_info->transfer_id = __bt_get_transfer_id(transfer_path);
814 transfer_info->file_path = agent_info.auth_info->file_path;
815 transfer_info->address = g_strdup(agent_info.auth_info->address);
817 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
818 for (i = 0; i < 5; i++)
819 g_variant_builder_add(builder, "y", agent_info.auth_info->contact_auth_info[i]);
821 param = g_variant_new("(isssstii(ay))", result,
822 transfer_info->device_name,
823 transfer_info->filename,
825 transfer_info->address,
826 transfer_info->file_size,
827 transfer_info->transfer_id,
828 agent_info.server_type,
830 _bt_send_event(BT_OPP_SERVER_EVENT,
831 BLUETOOTH_EVENT_OBEX_SERVER_TRANSFER_STARTED,
833 g_variant_builder_unref(builder);
835 param = g_variant_new("(issssstii)", result,
836 transfer_info->filename,
838 transfer_info->device_name,
839 transfer_info->file_path,
840 transfer_info->address,
841 transfer_info->file_size,
842 transfer_info->transfer_id,
843 agent_info.server_type);
844 _bt_send_event(BT_OPP_SERVER_EVENT,
845 BLUETOOTH_EVENT_OBEX_SERVER_TRANSFER_COMPLETED,
847 transfers = g_slist_remove(transfers, transfer_info);
848 __bt_free_transfer_info(transfer_info);
851 void _bt_obex_transfer_connected(const char *obj_path)
855 int result = BLUETOOTH_ERROR_NONE;
856 GVariant *param = NULL;
857 bt_transfer_info_t *transfer_info = NULL;
859 transfer_info = g_new0(bt_transfer_info_t, 1);
860 __bt_get_transfer_properties(transfer_info, obj_path);
861 INFO_SECURE("Address[%s] Name[%s] TransferID[%d] ", transfer_info->address,
862 transfer_info->device_name, transfer_info->transfer_id);
864 param = g_variant_new("(issi)", result, transfer_info->address,
865 transfer_info->device_name, transfer_info->transfer_id);
867 _bt_send_event(BT_OPP_SERVER_EVENT,
868 BLUETOOTH_EVENT_OBEX_SERVER_TRANSFER_CONNECTED,
871 __bt_free_transfer_info(transfer_info);
875 void _bt_obex_transfer_disconnected(char * obj_path)
879 int result = BLUETOOTH_ERROR_NONE;
880 GVariant *param = NULL;
881 bt_session_info_t *session = NULL;
882 int transfer_id = -1;
884 session = __bt_find_session_by_path(obj_path);
885 ret_if(session == NULL);
887 transfer_id = __bt_get_transfer_id(obj_path);
888 DBG_SECURE("transfer_id: [%d]", transfer_id);
890 DBG_SECURE("%s", session->address);
891 param = g_variant_new("(isi)", result, session->address, transfer_id);
892 _bt_send_event(BT_OPP_SERVER_EVENT,
893 BLUETOOTH_EVENT_OBEX_SERVER_TRANSFER_DISCONNECTED,
895 session_list = g_slist_remove(session_list, session);
896 g_free(session->address);
897 g_free(session->path);
902 int _bt_register_obex_server(void)
904 GDBusConnection *g_conn;
905 GDBusProxy *manager_proxy;
906 GVariant *result = NULL;
907 GError *g_error = NULL;
909 /* Get the session bus. */
910 g_conn = _bt_gdbus_get_system_gconn();
911 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
913 _bt_obex_agent_new(BT_OBEX_SERVER_AGENT_PATH);
915 _bt_obex_setup(BT_OBEX_SERVER_AGENT_PATH);
917 _bt_obex_set_authorize_cb(BT_OBEX_SERVER_AGENT_PATH,
918 __bt_authorize_cb, NULL);
920 manager_proxy = g_dbus_proxy_new_sync(g_conn, G_DBUS_PROXY_FLAGS_NONE,
921 NULL, BT_OBEX_SERVICE,
926 if (manager_proxy == NULL)
927 return BLUETOOTH_ERROR_INTERNAL;
929 result = g_dbus_proxy_call_sync(manager_proxy, "RegisterAgent",
930 g_variant_new("(o)", BT_OBEX_SERVER_AGENT_PATH),
931 G_DBUS_CALL_FLAGS_NONE,
935 if (g_error != NULL) {
936 BT_ERR("Agent registration failed: %s\n", g_error->message);
937 g_object_unref(manager_proxy);
938 g_error_free(g_error);
939 return BLUETOOTH_ERROR_INTERNAL;
943 g_variant_unref(result);
945 agent_info.proxy = manager_proxy;
947 return BLUETOOTH_ERROR_NONE;
950 int _bt_unregister_obex_server(void)
952 GVariant *result = NULL;
953 GError *g_error = NULL;
955 retv_if(agent_info.proxy == NULL,
956 BLUETOOTH_ERROR_INTERNAL);
958 result = g_dbus_proxy_call_sync(agent_info.proxy, "UnregisterAgent",
959 g_variant_new("(o)", BT_OBEX_SERVER_AGENT_PATH),
960 G_DBUS_CALL_FLAGS_NONE,
963 if (g_error != NULL) {
964 BT_ERR("Agent unregistration failed: %s", g_error->message);
965 g_error_free(g_error);
969 g_variant_unref(result);
971 _bt_obex_agent_destroy(BT_OBEX_SERVER_AGENT_PATH);
972 g_object_unref(agent_info.proxy);
973 agent_info.proxy = NULL;
975 return BLUETOOTH_ERROR_NONE;
978 gboolean __bt_check_folder_path(const char *dest_path)
982 retv_if(dest_path == NULL, FALSE);
984 dp = opendir(dest_path);
987 BT_ERR("The directory does not exist");
996 char *__bt_transfer_folder_path(char *dest_path)
998 char *dst_path = (char *)g_malloc0(BT_OBEX_PATH_MAX_LENGTH);
999 if (g_str_has_prefix(dest_path, BT_OBEX_PATH_PREFIX))
1000 snprintf(dst_path, BT_OBEX_PATH_MAX_LENGTH, BT_OBEX_DEFAULT_PATH"%s", dest_path + strlen(BT_OBEX_PATH_PREFIX));
1002 snprintf(dst_path, BT_OBEX_PATH_MAX_LENGTH, "%s", dest_path);
1004 BT_INFO("obex transfed path : %s", dst_path);
1008 int _bt_obex_server_allocate(char *sender, const char *dest_path, int app_pid, gboolean is_native)
1013 dst_path = __bt_transfer_folder_path((char *)dest_path);
1015 if (__bt_check_folder_path(dst_path) == FALSE) {
1017 return BLUETOOTH_ERROR_INVALID_PARAM;
1020 if (is_native == TRUE) {
1021 if (agent_info.native_server) {
1022 BT_ERR("obex native server busy");
1024 return BLUETOOTH_ERROR_DEVICE_BUSY;
1027 /* Force to change the control to native */
1028 agent_info.native_server = g_malloc0(sizeof(bt_server_info_t));
1029 agent_info.native_server->dest_path = g_strdup(dst_path);
1030 agent_info.native_server->sender = g_strdup(sender);
1031 agent_info.native_server->app_pid = app_pid;
1032 agent_info.server_type = BT_NATIVE_SERVER;
1033 _bt_unregister_osp_server_in_agent(BT_OBEX_SERVER, NULL);
1035 if (agent_info.custom_server) {
1036 BT_ERR("obex custom server busy");
1038 return BLUETOOTH_ERROR_DEVICE_BUSY;
1041 /* Force to change the control to custom */
1042 agent_info.custom_server = g_malloc0(sizeof(bt_server_info_t));
1043 agent_info.custom_server->dest_path = g_strdup(dst_path);
1044 agent_info.custom_server->sender = g_strdup(sender);
1045 agent_info.custom_server->app_pid = app_pid;
1046 agent_info.server_type = BT_CUSTOM_SERVER;
1047 _bt_register_osp_server_in_agent(BT_OBEX_SERVER, NULL, NULL, -1);
1052 return BLUETOOTH_ERROR_NONE;
1055 int _bt_obex_server_deallocate(int app_pid, gboolean is_native)
1057 if (is_native == TRUE) {
1058 retv_if(agent_info.native_server == NULL,
1059 BLUETOOTH_ERROR_AGENT_DOES_NOT_EXIST);
1061 retv_if(agent_info.native_server->app_pid != app_pid,
1062 BLUETOOTH_ERROR_ACCESS_DENIED);
1064 __bt_free_server_info(agent_info.native_server);
1065 agent_info.native_server = NULL;
1067 /* Change the control to custom */
1068 if (agent_info.custom_server) {
1069 agent_info.server_type = BT_CUSTOM_SERVER;
1070 _bt_register_osp_server_in_agent(BT_OBEX_SERVER,
1074 retv_if(agent_info.custom_server == NULL,
1075 BLUETOOTH_ERROR_AGENT_DOES_NOT_EXIST);
1077 retv_if(agent_info.custom_server->app_pid != app_pid,
1078 BLUETOOTH_ERROR_ACCESS_DENIED);
1080 __bt_free_server_info(agent_info.custom_server);
1081 agent_info.custom_server = NULL;
1083 _bt_unregister_osp_server_in_agent(BT_OBEX_SERVER, NULL);
1085 /* Change the control to native */
1086 if (agent_info.native_server)
1087 agent_info.server_type = BT_NATIVE_SERVER;
1090 return BLUETOOTH_ERROR_NONE;
1093 int _bt_obex_server_accept_authorize(const char *filename, gboolean is_native)
1095 char file_path[BT_FILE_PATH_MAX] = { 0 };
1096 bt_server_info_t *server_info;
1098 BT_CHECK_PARAMETER(filename, return);
1100 retv_if(agent_info.auth_info == NULL, BLUETOOTH_ERROR_INTERNAL);
1102 retv_if(agent_info.auth_info->reply_context == NULL,
1103 BLUETOOTH_ERROR_INTERNAL);
1105 if (is_native == TRUE)
1106 server_info = agent_info.native_server;
1108 server_info = agent_info.custom_server;
1110 retv_if(server_info == NULL, BLUETOOTH_ERROR_INTERNAL);
1112 if (server_info->dest_path != NULL)
1113 snprintf(file_path, sizeof(file_path), "%s/%s",
1114 server_info->dest_path, filename);
1116 snprintf(file_path, sizeof(file_path), "%s", filename);
1118 g_dbus_method_invocation_return_value(agent_info.auth_info->reply_context,
1119 g_variant_new("(s)", &file_path));
1120 agent_info.auth_info->reply_context = NULL;
1121 agent_info.auth_info->file_path = g_strdup(file_path);
1122 g_free(agent_info.auth_info->filename);
1123 agent_info.auth_info->filename = g_strdup(filename);
1125 return BLUETOOTH_ERROR_NONE;
1128 void _bt_obex_server_reply_accept(void)
1130 GVariant *param = NULL;
1131 bt_session_info_t *session_info = NULL;
1132 int result = BLUETOOTH_ERROR_NONE;
1133 param = g_variant_new("(istss)", result,
1134 agent_info.auth_info->filename,
1135 agent_info.auth_info->file_size,
1136 agent_info.auth_info->address,
1137 agent_info.auth_info->device_name);
1138 BT_INFO("Send Obex Authorize");
1139 _bt_send_event(BT_OPP_SERVER_EVENT, BLUETOOTH_EVENT_OBEX_SERVER_TRANSFER_AUTHORIZE, param);
1141 session_info = __bt_find_session_by_path(agent_info.auth_info->transfer_path);
1143 if (NULL == session_info)
1144 BT_ERR("Couldn't get the session info from the list");
1146 session_info->authorized = TRUE;
1149 int _bt_obex_server_reject_authorize(void)
1153 retv_if(agent_info.auth_info->reply_context == NULL,
1154 BLUETOOTH_ERROR_INTERNAL);
1156 g_error = g_error_new(__bt_obex_error_quark(),
1157 BT_OBEX_AGENT_ERROR_CANCEL,
1160 g_dbus_method_invocation_return_gerror(agent_info.auth_info->reply_context,
1162 g_error_free(g_error);
1164 __bt_free_auth_info(agent_info.auth_info);
1165 agent_info.auth_info = NULL;
1167 return BLUETOOTH_ERROR_NONE;
1170 int _bt_obex_server_set_destination_path(const char *dest_path,
1173 bt_server_info_t *server_info;
1174 BT_CHECK_PARAMETER(dest_path, return);
1177 dst_path = __bt_transfer_folder_path((char *)dest_path);
1181 dp = opendir(dst_path);
1184 BT_ERR("The directory does not exist");
1186 return BLUETOOTH_ERROR_INVALID_PARAM;
1191 if (is_native == TRUE)
1192 server_info = agent_info.native_server;
1194 server_info = agent_info.custom_server;
1197 BT_ERR("obex server info is NULL");
1199 return BLUETOOTH_ERROR_AGENT_DOES_NOT_EXIST;
1202 g_free(server_info->dest_path);
1203 server_info->dest_path = g_strdup(dst_path);
1206 return BLUETOOTH_ERROR_NONE;
1209 int _bt_obex_server_set_root(const char *root)
1211 GVariant *result = NULL;
1212 GError *g_error = NULL;
1213 GVariant *folder = NULL;
1214 char *string = "Root";
1217 BT_CHECK_PARAMETER(root, return);
1220 dst_root = __bt_transfer_folder_path((char *)root);
1222 if (!agent_info.proxy) {
1223 BT_ERR("obex agent_info proxy error");
1225 return BLUETOOTH_ERROR_INTERNAL;
1228 dp = opendir(dst_root);
1231 BT_ERR("The directory does not exist");
1233 return BLUETOOTH_ERROR_INVALID_PARAM;
1238 folder = g_variant_new_string(dst_root);
1239 result = g_dbus_proxy_call_sync(agent_info.proxy, "SetProperty",
1240 g_variant_new("(sv)", string, folder),
1241 G_DBUS_CALL_FLAGS_NONE,
1246 BT_ERR("SetProperty Fail: %s", g_error->message);
1247 g_error_free(g_error);
1249 return BLUETOOTH_ERROR_INTERNAL;
1253 g_variant_unref(result);
1256 return BLUETOOTH_ERROR_NONE;
1259 int _bt_obex_server_cancel_transfer(int transfer_id)
1261 bt_transfer_info_t *transfer = NULL;
1263 GVariant *result = NULL;
1266 transfer = __bt_find_transfer_by_id(transfer_id);
1268 retv_if(transfer == NULL, BLUETOOTH_ERROR_NOT_FOUND);
1269 proxy = __bt_get_transfer_proxy(transfer->path);
1271 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1273 result = g_dbus_proxy_call_sync(proxy, "Cancel", NULL,
1274 G_DBUS_CALL_FLAGS_NONE,
1275 DBUS_TIMEOUT, NULL, &err);
1277 BT_ERR("Dbus Err: %s", err->message);
1278 g_clear_error(&err);
1281 g_object_unref(proxy);
1284 g_variant_unref(result);
1286 return BLUETOOTH_ERROR_NONE;
1289 int _bt_obex_server_cancel_all_transfers(void)
1292 bt_transfer_info_t *transfer;
1294 for (l = transfers; l != NULL; l = l->next) {
1297 if (transfer == NULL)
1300 _bt_obex_server_cancel_transfer(transfer->transfer_id);
1303 return BLUETOOTH_ERROR_NONE;
1306 int _bt_obex_server_is_activated(gboolean *activated)
1308 BT_CHECK_PARAMETER(activated, return);
1310 if (agent_info.custom_server)
1315 return BLUETOOTH_ERROR_NONE;
1318 int _bt_obex_server_check_allocation(gboolean *allocation)
1320 BT_CHECK_PARAMETER(allocation, return);
1322 if (agent_info.native_server || agent_info.custom_server)
1325 *allocation = FALSE;
1327 return BLUETOOTH_ERROR_NONE;
1330 int _bt_obex_server_check_termination(char *sender)
1332 BT_CHECK_PARAMETER(sender, return);
1334 if (agent_info.native_server) {
1335 if (g_strcmp0(sender, agent_info.native_server->sender) == 0) {
1336 _bt_obex_server_deallocate(agent_info.native_server->app_pid,
1341 if (agent_info.custom_server) {
1342 if (g_strcmp0(sender, agent_info.custom_server->sender) == 0) {
1343 _bt_obex_server_deallocate(agent_info.custom_server->app_pid,
1348 return BLUETOOTH_ERROR_NONE;
1351 int _bt_obex_server_is_receiving(gboolean *receiving)
1353 BT_CHECK_PARAMETER(receiving, return);
1355 if (transfers == NULL || g_slist_length(transfers) == 0)
1360 return BLUETOOTH_ERROR_NONE;
1363 gboolean __bt_obex_server_accept_timeout_cb(gpointer user_data)
1365 request_info_t *req_info;
1366 GVariant *out_param1 = NULL;
1367 int result = BLUETOOTH_ERROR_TIMEOUT;
1369 /* Already reply in _bt_obex_transfer_started */
1370 retv_if(agent_info.accept_id == 0, FALSE);
1372 req_info = _bt_get_request_info(agent_info.accept_id);
1373 if (req_info == NULL || req_info->context == NULL) {
1374 BT_ERR("info is NULL");
1378 agent_info.accept_id = 0;
1379 GArray *g_out_param1 = NULL;
1380 g_out_param1 = g_array_new(FALSE, FALSE, sizeof(gchar));
1381 if (out_param1 == NULL) {
1382 out_param1 = g_variant_new_from_data((const GVariantType *)"ay",
1383 g_out_param1->data, g_out_param1->len,
1387 g_dbus_method_invocation_return_value(req_info->context,
1388 g_variant_new("(iv)", result, out_param1));
1389 g_array_free(g_out_param1, TRUE);
1390 _bt_delete_request_list(req_info->req_id);
1395 /* To support the BOT */
1396 int _bt_obex_server_accept_connection(int request_id)
1398 if (!_bt_agent_reply_authorize(TRUE))
1399 return BLUETOOTH_ERROR_INTERNAL;
1401 agent_info.accept_id = request_id;
1403 g_timeout_add(BT_SERVER_ACCEPT_TIMEOUT,
1404 (GSourceFunc)__bt_obex_server_accept_timeout_cb,
1407 return BLUETOOTH_ERROR_NONE;
1410 /* To support the BOT */
1411 int _bt_obex_server_reject_connection(void)
1413 if (!_bt_agent_reply_authorize(FALSE))
1414 return BLUETOOTH_ERROR_INTERNAL;
1416 return BLUETOOTH_ERROR_NONE;
1419 int _bt_opp_get_server_progress(int transfer_id, guint8 *progress)
1421 bt_transfer_info_t *requested_transfer = NULL;
1422 requested_transfer = __bt_find_transfer_by_id(transfer_id);
1423 if (requested_transfer == NULL) {
1424 BT_ERR("No Matching Inbound transfer");
1425 return BLUETOOTH_ERROR_NOT_FOUND;
1428 *progress = (int)(((double)requested_transfer->progress /
1429 requested_transfer->file_size) * 100);
1431 BT_DBG("Percentage: %d", *progress);
1432 return BLUETOOTH_ERROR_NONE;