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"
40 #include <oal-device-mgr.h>
42 #define DBUS_TIMEOUT 20 * 1000 /* 20 Seconds */
43 #define BT_OBEX_SERVER_AGENT_PATH "/org/obex/server_agent"
45 #define BT_OBEX_SERVICE "org.bluez.obex"
46 #define BT_OBEX_MANAGER "org.bluez.obex.AgentManager1"
47 #define BT_OBEX_PATH "/org/bluez/obex"
49 #define BT_OBEX_PATH_PREFIX "/opt/usr/media"
50 #define BT_OBEX_DEFAULT_PATH "/opt/usr/home/owner/media"
51 #define BT_OBEX_PATH_MAX_LENGTH 255
67 GDBusMethodInvocation *reply_context;
74 unsigned char contact_auth_info[5];
87 bt_auth_info_t *auth_info;
88 bt_server_info_t *native_server;
89 bt_server_info_t *custom_server;
90 } bt_obex_agent_info_t;
98 static GSList *transfers;
99 static bt_obex_agent_info_t agent_info;
100 static GSList *session_list = NULL;
102 static char *pending_auth_address = NULL;
104 static bt_session_info_t *__bt_find_session_by_path(char *transfer_path)
107 bt_session_info_t *session;
109 retv_if(transfer_path == NULL, NULL);
111 for (l = session_list; l != NULL; l = l->next) {
117 if (g_strcmp0(session->path, transfer_path) == 0)
124 static GQuark __bt_obex_error_quark(void)
126 static GQuark quark = 0;
128 quark = g_quark_from_static_string("agent");
133 static bt_transfer_info_t *__bt_find_transfer_by_id(int transfer_id)
136 bt_transfer_info_t *transfer;
138 for (l = transfers; l != NULL; l = l->next) {
141 if (transfer == NULL)
144 if (transfer->transfer_id == transfer_id)
151 bt_transfer_info_t *__bt_find_transfer_by_address(const char *address)
155 bt_transfer_info_t *transfer;
157 retv_if(address == NULL, NULL);
159 for (l = transfers; l != NULL; l = l->next) {
162 if (transfer == NULL)
165 if (g_strcmp0(transfer->address, address) == 0)
172 static bt_transfer_info_t *__bt_find_transfer_by_path(const char *transfer_path)
175 bt_transfer_info_t *transfer;
177 retv_if(transfer_path == NULL, NULL);
179 for (l = transfers; l != NULL; l = l->next) {
182 if (transfer == NULL)
185 if (g_strcmp0(transfer->path, transfer_path) == 0)
192 static void __bt_free_server_info(bt_server_info_t *server_info)
194 ret_if(server_info == NULL);
196 g_free(server_info->sender);
197 g_free(server_info->dest_path);
201 static void __bt_free_auth_info(bt_auth_info_t *auto_info)
203 ret_if(auto_info == NULL);
205 g_free(auto_info->filename);
206 g_free(auto_info->transfer_path);
207 g_free(auto_info->device_name);
208 g_free(auto_info->address);
212 static void __bt_free_transfer_info(bt_transfer_info_t *transfer_info)
214 ret_if(transfer_info == NULL);
216 g_free(transfer_info->path);
217 g_free(transfer_info->filename);
218 g_free(transfer_info->file_path);
219 g_free(transfer_info->type);
220 g_free(transfer_info->device_name);
221 g_free(transfer_info->address);
222 g_free(transfer_info);
225 void _bt_obex_check_pending_transfer(const char *address)
228 GVariant *param = NULL;
229 bt_transfer_info_t *transfer_info = __bt_find_transfer_by_address(address);
230 if (transfer_info != NULL) {
231 int result = BLUETOOTH_ERROR_CANCEL;
232 param = g_variant_new("(issssstii)", result,
233 transfer_info->filename,
235 transfer_info->device_name,
236 transfer_info->file_path,
237 transfer_info->address,
238 transfer_info->file_size,
239 transfer_info->transfer_id,
240 agent_info.server_type);
241 _bt_send_event(BT_OPP_SERVER_EVENT,
242 BLUETOOTH_EVENT_OBEX_SERVER_TRANSFER_COMPLETED,
244 transfers = g_slist_remove(transfers, transfer_info);
245 __bt_free_transfer_info(transfer_info);
250 static char *__bt_get_remote_device_name(const char *bdaddress)
252 char *device_path = NULL;
255 GVariant *result = NULL;
257 GDBusProxy *device_proxy;
258 GDBusConnection *conn;
260 retv_if(bdaddress == NULL, NULL);
262 conn = _bt_get_system_gconn();
263 retv_if(conn == NULL, NULL);
265 device_path = _bt_get_device_object_path((char *)bdaddress);
266 retv_if(device_path == NULL, NULL);
268 BT_INFO("Device_path %s", device_path);
269 device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
272 BT_PROPERTIES_INTERFACE,
276 retv_if(device_proxy == NULL, NULL);
278 result = g_dbus_proxy_call_sync(device_proxy, "GetAll",
279 g_variant_new("(s)", BT_DEVICE_INTERFACE),
280 G_DBUS_CALL_FLAGS_NONE,
284 BT_ERR("DBus Error : %s", err->message);
288 if (result == NULL) {
289 BT_ERR("g_dbus_proxy_call_sync function return NULL");
292 g_variant_get(result, "(@a{sv})", &value);
295 GVariant *temp_value = g_variant_lookup_value(value, "Alias",
296 G_VARIANT_TYPE_STRING);
297 g_variant_get(temp_value, "s", &name);
299 g_variant_unref(temp_value);
302 DBG_SECURE("Alias Name [%s]", name);
304 temp_value = g_variant_lookup_value(value, "Name", G_VARIANT_TYPE_STRING);
305 g_variant_get(temp_value, "s", &name);
307 g_variant_unref(temp_value);
308 DBG_SECURE("Name = %s", name);
311 g_variant_unref(result);
312 g_object_unref(device_proxy);
316 void __bt_get_auth_info(GVariant *reply, char *auth_info)
320 char *manufacturer_data = NULL;
321 int manufacturer_data_len;
322 gboolean is_alias_set;
323 GVariantIter *value_iter;
327 tmp_value = g_variant_lookup_value(reply, "IsAliasSet",
328 G_VARIANT_TYPE_BOOLEAN);
330 is_alias_set = g_variant_get_boolean(tmp_value);
331 g_variant_unref(tmp_value);
333 is_alias_set = FALSE;
335 if (is_alias_set == FALSE) {
336 tmp_value = g_variant_lookup_value(reply, "LegacyManufacturerDataLen",
337 G_VARIANT_TYPE_UINT16);
339 manufacturer_data_len = g_variant_get_uint16(tmp_value);
340 if (manufacturer_data_len >
341 BLUETOOTH_MANUFACTURER_DATA_LENGTH_MAX) {
342 BT_ERR("manufacturer_data_len is too long");
343 manufacturer_data_len = BLUETOOTH_MANUFACTURER_DATA_LENGTH_MAX;
345 g_variant_unref(tmp_value);
347 manufacturer_data_len = 0;
349 tmp_value = g_variant_lookup_value(reply, "LegacyManufacturerData",
350 G_VARIANT_TYPE_ARRAY);
352 if ((manufacturer_data_len == 0) ||
353 manufacturer_data_len != g_variant_get_size(tmp_value)) {
354 BT_ERR("manufacturer data length doesn't match");
355 manufacturer_data_len = 0;
356 manufacturer_data = NULL;
358 manufacturer_data = g_malloc0(manufacturer_data_len);
359 g_variant_get(tmp_value, "ay", &value_iter);
360 while (g_variant_iter_loop(value_iter, "y", &m_value))
361 manufacturer_data[i++] = m_value;
363 g_variant_iter_free(value_iter);
365 g_variant_unref(tmp_value);
367 BT_INFO("manufacture data is not a G_VARIANT_TYPE_ARRAY ");
368 manufacturer_data_len = 0;
369 manufacturer_data = NULL;
371 /*minimum Size of the samsung specific manufacturer data is greater than 30 */
372 if (manufacturer_data_len < 30) {
373 g_free(manufacturer_data);
376 if (manufacturer_data[0] != 0x00 || manufacturer_data[1] != 0x75) {
377 BT_DBG("This is not a samsung specific manufaturer data");
378 g_free(manufacturer_data);
382 /* 2 samsung (0x00 0x75) + 1 (control and version) + 1 (service ID) +
383 1 (discovery version) + 1 (associated service ID)
384 2 (Proxamity and locality) + 2 (Device type and icon) */
388 memcpy(auth_info, &(manufacturer_data[cursor]), 5);
390 g_free(manufacturer_data);
393 static void __bt_get_remote_device_name_authinfo(const char *bdaddress,
394 char **device_name, unsigned char *auth_info)
396 char *device_path = NULL;
398 gboolean is_alias_set;
400 GVariant *result = NULL;
402 GDBusProxy *device_proxy;
403 GDBusConnection *conn;
405 ret_if(bdaddress == NULL);
407 conn = _bt_get_system_gconn();
408 ret_if(conn == NULL);
410 device_path = _bt_get_device_object_path((char *)bdaddress);
411 ret_if(device_path == NULL);
413 BT_INFO("Device_path %s", device_path);
414 device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
417 BT_PROPERTIES_INTERFACE,
421 ret_if(device_proxy == NULL);
423 result = g_dbus_proxy_call_sync(device_proxy, "GetAll",
424 g_variant_new("(s)", BT_DEVICE_INTERFACE),
425 G_DBUS_CALL_FLAGS_NONE,
429 BT_ERR("DBus Error : %s", err->message);
433 if (result == NULL) {
434 BT_ERR("g_dbus_proxy_call_sync function return NULL");
437 g_variant_get(result, "(@a{sv})", &value);
440 GVariant *temp_value = g_variant_lookup_value(value, "Alias",
441 G_VARIANT_TYPE_STRING);
442 g_variant_get(temp_value, "s", &name);
444 g_variant_unref(temp_value);
447 DBG_SECURE("Alias Name [%s]", name);
449 temp_value = g_variant_lookup_value(value, "Name", G_VARIANT_TYPE_STRING);
450 g_variant_get(temp_value, "s", &name);
452 g_variant_unref(temp_value);
453 DBG_SECURE("Name = %s", name);
455 temp_value = g_variant_lookup_value(value, "IsAliasSet", G_VARIANT_TYPE_BOOLEAN);
457 is_alias_set = g_variant_get_boolean(temp_value);
458 g_variant_unref(temp_value);
460 is_alias_set = FALSE;
463 if (is_alias_set == FALSE) {
464 DBG_SECURE("Do Nothing");
465 __bt_get_auth_info(value, (char *)auth_info);
468 g_variant_unref(result);
469 g_object_unref(device_proxy);
471 *device_name = g_strdup(name);
476 static int __bt_get_transfer_id(const char *path)
482 tmp = strrchr(path, 'r') + 1;
483 retv_if(tmp == NULL, -1);
488 static GDBusProxy *__bt_get_transfer_proxy(const char *transfer_path)
490 GDBusConnection *conn;
494 conn = _bt_get_system_gconn();
495 retv_if(conn == NULL, NULL);
497 proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
498 NULL, BT_OBEX_SERVICE_NAME,
500 BT_OBEX_TRANSFER_INTERFACE,
504 BT_ERR("Error : %s", err->message);
512 static GDBusProxy *__bt_get_transfer_properties_proxy(const char *transfer_path)
514 GDBusConnection *conn;
517 conn = _bt_get_system_gconn();
518 retv_if(conn == NULL, NULL);
520 proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
521 NULL, BT_OBEX_SERVICE_NAME,
523 BT_PROPERTIES_INTERFACE,
526 BT_ERR("Error : %s", err->message);
533 static int __bt_get_transfer_properties(bt_transfer_info_t *transfer_info,
534 const char *transfer_path)
536 GDBusProxy *transfer_proxy;
537 GVariant *result = NULL;
539 GVariantIter *iter = NULL;
540 BT_CHECK_PARAMETER(transfer_info, return);
541 BT_CHECK_PARAMETER(transfer_path, return);
543 transfer_proxy = __bt_get_transfer_properties_proxy(transfer_path);
545 retv_if(transfer_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
547 result = g_dbus_proxy_call_sync(transfer_proxy, "GetAll",
548 g_variant_new("(s)", BT_OBEX_TRANSFER_INTERFACE),
549 G_DBUS_CALL_FLAGS_NONE,
554 BT_ERR("DBus Error : %s", err->message);
558 if (result == NULL) {
559 BT_ERR("g_dbus_proxy_call_sync function return NULL");
563 g_variant_get(result, "(a{sv})", &iter);
564 g_variant_unref(result);
569 while (g_variant_iter_loop(iter, "{sv}", &key, &val)) {
570 if (g_strcmp0(key, "Operation") == 0) {
571 transfer_info->type = g_variant_dup_string(val, &len);
572 } else if (g_strcmp0(key, "Name") == 0) {
573 transfer_info->filename = g_variant_dup_string(val, &len);
574 } else if (g_strcmp0(key, "Size") == 0) {
575 transfer_info->file_size = g_variant_get_uint64(val);
576 } else if (g_strcmp0(key, "Address") == 0) {
577 transfer_info->address = g_variant_dup_string(val, &len);
578 BT_INFO("addressss %s", transfer_info->address);
579 } else if (g_strcmp0(key, "Filename") == 0) {
580 transfer_info->file_path = g_variant_dup_string(val, &len);
581 if (!transfer_info->file_path)
582 transfer_info->file_path = g_strdup(transfer_info->filename);
585 g_variant_iter_free(iter);
587 if (transfer_info->address == NULL)
589 transfer_info->device_name = __bt_get_remote_device_name(transfer_info->address);
590 transfer_info->transfer_id = __bt_get_transfer_id(transfer_path);
591 if (!transfer_info->device_name)
592 transfer_info->device_name = g_strdup(transfer_info->address);
594 if (transfer_info->type == NULL)
597 transfer_info->path = g_strdup(transfer_path);
600 g_object_unref(transfer_proxy);
601 return BLUETOOTH_ERROR_NONE;
604 g_object_unref(transfer_proxy);
605 return BLUETOOTH_ERROR_INTERNAL;
608 static gboolean __bt_authorize_cb(GDBusMethodInvocation *context,
612 char *device_name = NULL;
613 unsigned char auth_info[5] = {0, };
614 int result = BLUETOOTH_ERROR_NONE;
615 GDBusProxy *transfer_properties_proxy;
616 char * bdaddress = NULL;
619 GVariant *param = NULL;
621 bt_session_info_t *session_info = NULL;
622 #ifdef TIZEN_FEATURE_BT_DPM
623 int value = DPM_BT_ERROR;
626 BT_DBG(" path [%s] \n", path);
628 transfer_properties_proxy = __bt_get_transfer_properties_proxy(path);
630 retv_if(transfer_properties_proxy == NULL, FALSE);
632 ret = g_dbus_proxy_call_sync(transfer_properties_proxy, "GetAll",
633 g_variant_new("(s)", BT_OBEX_TRANSFER_INTERFACE),
634 G_DBUS_CALL_FLAGS_NONE,
638 BT_ERR("DBus Error : %s", err->message);
643 BT_ERR("g_dbus_proxy_call_sync function return NULL");
646 g_variant_get(ret, "(a{sv})", &iter);
647 g_variant_unref(ret);
649 g_object_unref(transfer_properties_proxy);
653 __bt_free_auth_info(agent_info.auth_info);
655 agent_info.auth_info = g_malloc(sizeof(bt_auth_info_t));
657 memset(agent_info.auth_info, 0, sizeof(bt_auth_info_t));
659 agent_info.auth_info->reply_context = context;
661 agent_info.auth_info->transfer_path = g_strdup(path);
663 #ifdef TIZEN_FEATURE_BT_DPM
664 _bt_dpm_get_allow_bluetooth_mode(&value);
665 if (value == DPM_BT_HANDSFREE_ONLY) {
666 /* Free auth info in next function */
667 _bt_obex_server_reject_authorize();
675 while (g_variant_iter_loop(iter, "{sv}", &key, &val)) {
676 if (g_strcmp0(key, "Name") == 0)
677 agent_info.auth_info->filename = g_variant_dup_string(val, &len);
678 else if (g_strcmp0(key, "Address") == 0)
679 bdaddress = g_variant_dup_string(val, &len);
680 else if (g_strcmp0(key, "Size") == 0)
681 agent_info.auth_info->file_size = g_variant_get_uint64(val);
683 g_variant_iter_free(iter);
686 __bt_get_remote_device_name_authinfo(bdaddress, &device_name, auth_info);
689 device_name = g_strdup(bdaddress);
691 agent_info.auth_info->address = g_strdup(bdaddress);
692 agent_info.auth_info->device_name = device_name;
693 memcpy(agent_info.auth_info->contact_auth_info, auth_info, 5);
695 session_info = __bt_find_session_by_path((char *)path);
696 if (NULL == session_info) {
697 session_info = g_malloc0(sizeof(bt_session_info_t));
698 session_info->path = g_strdup(path);
699 session_info->address = g_strdup(bdaddress);
700 session_info->authorized = FALSE;
701 session_list = g_slist_append(session_list, session_info);
704 g_object_unref(transfer_properties_proxy);
707 if (agent_info.server_type == BT_CUSTOM_SERVER) {
708 /* No need to send the event */
709 _bt_obex_server_accept_authorize(agent_info.auth_info->filename, FALSE);
713 if (session_info->authorized == FALSE) {
714 if (headed_plugin_info->plugin_headed_enabled)
715 headed_plugin_info->headed_plugin->bt_launch_system_popup(BT_AGENT_EVENT_EXCHANGE_REQUEST, device_name,
716 auth_info, NULL, NULL, BT_OBEX_SERVER_AGENT_PATH);
718 /* TODO_40 : 4.0 merge */
719 param = g_variant_new("(istss)", result,
720 agent_info.auth_info->filename,
721 agent_info.auth_info->file_size,
722 agent_info.auth_info->address,
723 agent_info.auth_info->device_name);
724 _bt_send_event(BT_OPP_SERVER_EVENT,
725 BLUETOOTH_EVENT_OBEX_SERVER_TRANSFER_AUTHORIZE, param);
731 void _bt_obex_transfer_started(const char *transfer_path)
733 bt_transfer_info_t *transfer_info;
734 request_info_t *req_info;
735 GVariant *out_param1 = NULL;
736 GVariant *param = NULL;
737 GVariantBuilder *builder = NULL;
738 int result = BLUETOOTH_ERROR_NONE;
741 BT_DBG("%s", transfer_path);
743 transfer_info = g_malloc0(sizeof(bt_transfer_info_t));
745 if (agent_info.auth_info != NULL
746 && g_strcmp0(transfer_path, agent_info.auth_info->transfer_path) == 0) {
747 transfer_info->filename = g_strdup(agent_info.auth_info->filename);
748 transfer_info->file_size = agent_info.auth_info->file_size;
749 transfer_info->type = g_strdup(TRANSFER_PUT);
750 transfer_info->path = g_strdup(agent_info.auth_info->transfer_path);
751 transfer_info->device_name = g_strdup(agent_info.auth_info->device_name);
752 transfer_info->transfer_id = __bt_get_transfer_id(transfer_path);
753 transfer_info->file_path = agent_info.auth_info->file_path;
754 transfer_info->address = g_strdup(agent_info.auth_info->address);
757 if (__bt_get_transfer_properties(transfer_info, transfer_path) < 0) {
758 BT_ERR("Get Properties failed");
759 __bt_free_transfer_info(transfer_info);
762 agent_info.server_type = BT_FTP_SERVER;
765 if (agent_info.server_type == BT_CUSTOM_SERVER) {
766 if (agent_info.custom_server == NULL) {
767 __bt_free_transfer_info(transfer_info);
768 __bt_free_auth_info(agent_info.auth_info);
769 agent_info.auth_info = NULL;
773 req_info = _bt_get_request_info(agent_info.accept_id);
774 if (req_info == NULL || req_info->context == NULL) {
775 BT_ERR("info is NULL");
779 agent_info.accept_id = 0;
780 result = BLUETOOTH_ERROR_NONE;
781 GArray *g_out_param1 = NULL;
782 g_out_param1 = g_array_new(FALSE, FALSE, sizeof(gchar));
783 if (out_param1 == NULL) {
784 out_param1 = g_variant_new_from_data((const GVariantType *)"ay",
785 g_out_param1->data, g_out_param1->len,
789 g_dbus_method_invocation_return_value(req_info->context,
790 g_variant_new("(iv)", result, out_param1));
791 g_array_free(g_out_param1, TRUE);
792 _bt_delete_request_list(req_info->req_id);
795 transfers = g_slist_append(transfers, transfer_info);
797 BT_DBG("Transfer id %d", transfer_info->transfer_id);
799 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
800 for (i = 0; i < 5; i++) {
801 if (agent_info.auth_info)
802 g_variant_builder_add(builder, "y", agent_info.auth_info->contact_auth_info[i]);
805 param = g_variant_new("(isssstii(ay))", result,
806 transfer_info->device_name,
807 transfer_info->filename,
809 transfer_info->address,
810 transfer_info->file_size,
811 transfer_info->transfer_id,
812 agent_info.server_type,
815 __bt_free_auth_info(agent_info.auth_info);
816 agent_info.auth_info = NULL;
818 g_variant_builder_unref(builder);
820 _bt_send_event(BT_OPP_SERVER_EVENT,
821 BLUETOOTH_EVENT_OBEX_SERVER_TRANSFER_STARTED,
825 void _bt_obex_transfer_progress(const char *transfer_path,
829 bt_transfer_info_t *transfer_info;
830 int current_progress = 0;
831 int previous_progress;
832 GVariant *param = NULL;
833 int result = BLUETOOTH_ERROR_NONE;
835 transfer_info = __bt_find_transfer_by_path(transfer_path);
836 ret_if(transfer_info == NULL);
838 current_progress = (int)(((gdouble)transferred /
839 (gdouble)transfer_info->file_size) * 100);
841 previous_progress = (int)(((gdouble)transfer_info->progress /
842 (gdouble)transfer_info->file_size) * 100);
844 if (current_progress == previous_progress) {
845 BT_DBG("Same Percentage Value: Do not emit Signal");
849 transfer_info->progress = transferred;
850 param = g_variant_new("(isssstiii)", result,
851 transfer_info->filename,
853 transfer_info->device_name,
854 transfer_info->address,
855 transfer_info->file_size,
856 transfer_info->transfer_id,
858 agent_info.server_type);
859 _bt_send_event(BT_OPP_SERVER_EVENT,
860 BLUETOOTH_EVENT_OBEX_SERVER_TRANSFER_PROGRESS,
865 void _bt_obex_transfer_completed(const char *transfer_path, gboolean success)
867 bt_transfer_info_t *transfer_info;
868 GVariantBuilder *builder = NULL;
869 GVariant *param = NULL;
872 BT_DBG("Transfer [%s] Success [%d] \n", transfer_path, success);
874 result = (success == TRUE) ? BLUETOOTH_ERROR_NONE
875 : BLUETOOTH_ERROR_CANCEL;
877 transfer_info = __bt_find_transfer_by_path(transfer_path);
879 if (transfer_info == NULL) {
880 BT_DBG("Very small files receiving case, did not get Active status from obexd");
881 if (agent_info.auth_info == NULL ||
882 g_strcmp0(transfer_path,
883 agent_info.auth_info->transfer_path) != 0) {
884 BT_ERR("auth_info is NULL, returning");
888 transfer_info = g_new0(bt_transfer_info_t, 1);
890 transfer_info->filename = g_strdup(agent_info.auth_info->filename);
891 transfer_info->file_size = agent_info.auth_info->file_size;
892 transfer_info->type = g_strdup(TRANSFER_PUT);
893 transfer_info->path = g_strdup(agent_info.auth_info->transfer_path);
894 transfer_info->device_name = g_strdup(agent_info.auth_info->device_name);
895 transfer_info->transfer_id = __bt_get_transfer_id(transfer_path);
896 transfer_info->file_path = agent_info.auth_info->file_path;
897 transfer_info->address = g_strdup(agent_info.auth_info->address);
899 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
900 for (i = 0; i < 5; i++)
901 g_variant_builder_add(builder, "y", agent_info.auth_info->contact_auth_info[i]);
903 param = g_variant_new("(isssstii(ay))", result,
904 transfer_info->device_name,
905 transfer_info->filename,
907 transfer_info->address,
908 transfer_info->file_size,
909 transfer_info->transfer_id,
910 agent_info.server_type,
912 _bt_send_event(BT_OPP_SERVER_EVENT,
913 BLUETOOTH_EVENT_OBEX_SERVER_TRANSFER_STARTED,
915 g_variant_builder_unref(builder);
917 param = g_variant_new("(issssstii)", result,
918 transfer_info->filename,
920 transfer_info->device_name,
921 transfer_info->file_path,
922 transfer_info->address,
923 transfer_info->file_size,
924 transfer_info->transfer_id,
925 agent_info.server_type);
926 _bt_send_event(BT_OPP_SERVER_EVENT,
927 BLUETOOTH_EVENT_OBEX_SERVER_TRANSFER_COMPLETED,
929 transfers = g_slist_remove(transfers, transfer_info);
930 __bt_free_transfer_info(transfer_info);
933 void _bt_obex_transfer_connected(const char *obj_path)
937 int result = BLUETOOTH_ERROR_NONE;
938 GVariant *param = NULL;
939 bt_transfer_info_t *transfer_info = NULL;
941 transfer_info = g_new0(bt_transfer_info_t, 1);
942 __bt_get_transfer_properties(transfer_info, obj_path);
943 DBG_SECURE("Address[%s] Name[%s] TransferID[%d] ", transfer_info->address,
944 transfer_info->device_name, transfer_info->transfer_id);
946 param = g_variant_new("(issi)", result, transfer_info->address,
947 transfer_info->device_name, transfer_info->transfer_id);
949 _bt_send_event(BT_OPP_SERVER_EVENT,
950 BLUETOOTH_EVENT_OBEX_SERVER_TRANSFER_CONNECTED,
953 __bt_free_transfer_info(transfer_info);
957 void _bt_obex_transfer_disconnected(char * obj_path)
961 int result = BLUETOOTH_ERROR_NONE;
962 GVariant *param = NULL;
963 bt_session_info_t *session = NULL;
964 int transfer_id = -1;
966 session = __bt_find_session_by_path(obj_path);
967 ret_if(session == NULL);
969 transfer_id = __bt_get_transfer_id(obj_path);
970 DBG_SECURE("transfer_id: [%d]", transfer_id);
972 DBG_SECURE("%s", session->address);
973 param = g_variant_new("(isi)", result, session->address, transfer_id);
974 _bt_send_event(BT_OPP_SERVER_EVENT,
975 BLUETOOTH_EVENT_OBEX_SERVER_TRANSFER_DISCONNECTED,
977 session_list = g_slist_remove(session_list, session);
978 g_free(session->address);
979 g_free(session->path);
984 int _bt_register_obex_server(void)
986 GDBusConnection *g_conn;
987 GDBusProxy *manager_proxy;
988 GVariant *result = NULL;
989 GError *g_error = NULL;
991 /* Get the session bus. */
992 g_conn = _bt_get_system_gconn();
993 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
995 _bt_obex_agent_new(BT_OBEX_SERVER_AGENT_PATH);
997 _bt_obex_setup(BT_OBEX_SERVER_AGENT_PATH);
999 _bt_obex_set_authorize_cb(BT_OBEX_SERVER_AGENT_PATH,
1000 __bt_authorize_cb, NULL);
1002 manager_proxy = g_dbus_proxy_new_sync(g_conn, G_DBUS_PROXY_FLAGS_NONE,
1003 NULL, BT_OBEX_SERVICE,
1008 if (manager_proxy == NULL)
1009 return BLUETOOTH_ERROR_INTERNAL;
1011 result = g_dbus_proxy_call_sync(manager_proxy, "RegisterAgent",
1012 g_variant_new("(o)", BT_OBEX_SERVER_AGENT_PATH),
1013 G_DBUS_CALL_FLAGS_NONE,
1017 if (g_error != NULL) {
1018 BT_ERR("Agent registration failed: %s\n", g_error->message);
1019 g_object_unref(manager_proxy);
1020 g_error_free(g_error);
1021 return BLUETOOTH_ERROR_INTERNAL;
1025 g_variant_unref(result);
1027 agent_info.proxy = manager_proxy;
1029 return BLUETOOTH_ERROR_NONE;
1032 int _bt_unregister_obex_server(void)
1034 GVariant *result = NULL;
1035 GError *g_error = NULL;
1037 retv_if(agent_info.proxy == NULL,
1038 BLUETOOTH_ERROR_INTERNAL);
1040 result = g_dbus_proxy_call_sync(agent_info.proxy, "UnregisterAgent",
1041 g_variant_new("(o)", BT_OBEX_SERVER_AGENT_PATH),
1042 G_DBUS_CALL_FLAGS_NONE,
1045 if (g_error != NULL) {
1046 BT_ERR("Agent unregistration failed: %s", g_error->message);
1047 g_error_free(g_error);
1051 g_variant_unref(result);
1053 _bt_obex_agent_destroy(BT_OBEX_SERVER_AGENT_PATH);
1054 g_object_unref(agent_info.proxy);
1055 agent_info.proxy = NULL;
1057 return BLUETOOTH_ERROR_NONE;
1060 gboolean __bt_check_folder_path(const char *dest_path)
1064 retv_if(dest_path == NULL, FALSE);
1066 dp = opendir(dest_path);
1069 BT_ERR("The directory does not exist");
1078 char *__bt_transfer_folder_path(char *dest_path)
1080 char *dst_path = (char *)g_malloc0(BT_OBEX_PATH_MAX_LENGTH);
1081 if (g_str_has_prefix(dest_path, BT_OBEX_PATH_PREFIX))
1082 snprintf(dst_path, BT_OBEX_PATH_MAX_LENGTH, BT_OBEX_DEFAULT_PATH"%s", dest_path + strlen(BT_OBEX_PATH_PREFIX));
1084 snprintf(dst_path, BT_OBEX_PATH_MAX_LENGTH, "%s", dest_path);
1086 BT_INFO("obex transfed path : %s", dst_path);
1090 int _bt_obex_server_allocate(char *sender, const char *dest_path, int app_pid, gboolean is_native)
1095 dst_path = __bt_transfer_folder_path((char *)dest_path);
1097 if (__bt_check_folder_path(dst_path) == FALSE) {
1099 return BLUETOOTH_ERROR_INVALID_PARAM;
1102 if (is_native == TRUE) {
1103 if (agent_info.native_server) {
1104 BT_ERR("obex native server busy");
1106 return BLUETOOTH_ERROR_DEVICE_BUSY;
1109 /* Force to change the control to native */
1110 agent_info.native_server = g_malloc0(sizeof(bt_server_info_t));
1111 agent_info.native_server->dest_path = g_strdup(dst_path);
1112 agent_info.native_server->sender = g_strdup(sender);
1113 agent_info.native_server->app_pid = app_pid;
1114 agent_info.server_type = BT_NATIVE_SERVER;
1115 if (OAL_STATUS_SUCCESS !=
1116 device_unregister_osp_server(OAL_OSP_SERVER_OBEX, NULL))
1117 BT_ERR("device_unregister_osp_server failed");
1119 if (agent_info.custom_server) {
1120 BT_ERR("obex custom server busy");
1122 return BLUETOOTH_ERROR_DEVICE_BUSY;
1125 /* Force to change the control to custom */
1126 agent_info.custom_server = g_malloc0(sizeof(bt_server_info_t));
1127 agent_info.custom_server->dest_path = g_strdup(dst_path);
1128 agent_info.custom_server->sender = g_strdup(sender);
1129 agent_info.custom_server->app_pid = app_pid;
1130 agent_info.server_type = BT_CUSTOM_SERVER;
1131 if (OAL_STATUS_SUCCESS !=
1132 device_register_osp_server(OAL_OSP_SERVER_OBEX, NULL, NULL, -1))
1133 BT_ERR("device_register_osp_server failed");
1138 return BLUETOOTH_ERROR_NONE;
1141 int _bt_obex_server_deallocate(int app_pid, gboolean is_native)
1143 if (is_native == TRUE) {
1144 retv_if(agent_info.native_server == NULL,
1145 BLUETOOTH_ERROR_AGENT_DOES_NOT_EXIST);
1147 retv_if(agent_info.native_server->app_pid != app_pid,
1148 BLUETOOTH_ERROR_ACCESS_DENIED);
1150 __bt_free_server_info(agent_info.native_server);
1151 agent_info.native_server = NULL;
1153 /* Change the control to custom */
1154 if (agent_info.custom_server &&
1155 agent_info.server_type != BT_CUSTOM_SERVER) {
1157 agent_info.server_type = BT_CUSTOM_SERVER;
1159 if (OAL_STATUS_SUCCESS !=
1160 device_register_osp_server(OAL_OSP_SERVER_OBEX, NULL, NULL, -1))
1161 BT_ERR("device_register_osp_server failed");
1164 retv_if(agent_info.custom_server == NULL,
1165 BLUETOOTH_ERROR_AGENT_DOES_NOT_EXIST);
1167 retv_if(agent_info.custom_server->app_pid != app_pid,
1168 BLUETOOTH_ERROR_ACCESS_DENIED);
1171 __bt_free_server_info(agent_info.custom_server);
1172 agent_info.custom_server = NULL;
1174 /* Change the control to native */
1175 if (agent_info.native_server &&
1176 agent_info.server_type != BT_NATIVE_SERVER) {
1178 agent_info.server_type = BT_NATIVE_SERVER;
1180 if (OAL_STATUS_SUCCESS !=
1181 device_unregister_osp_server(OAL_OSP_SERVER_OBEX, NULL))
1182 BT_ERR("device_unregister_osp_server failed");
1186 return BLUETOOTH_ERROR_NONE;
1189 int _bt_obex_server_accept_authorize(const char *filename, gboolean is_native)
1191 char file_path[BT_FILE_PATH_MAX] = { 0 };
1192 bt_server_info_t *server_info;
1193 bt_auth_info_t *new_auth_info;
1195 BT_CHECK_PARAMETER(filename, return);
1197 retv_if(agent_info.auth_info == NULL, BLUETOOTH_ERROR_INTERNAL);
1199 retv_if(agent_info.auth_info->reply_context == NULL,
1200 BLUETOOTH_ERROR_INTERNAL);
1202 if (is_native == TRUE)
1203 server_info = agent_info.native_server;
1205 server_info = agent_info.custom_server;
1207 retv_if(server_info == NULL, BLUETOOTH_ERROR_INTERNAL);
1209 if (server_info->dest_path != NULL)
1210 snprintf(file_path, sizeof(file_path), "%s/%s",
1211 server_info->dest_path, filename);
1213 snprintf(file_path, sizeof(file_path), "%s", filename);
1215 g_dbus_method_invocation_return_value(agent_info.auth_info->reply_context,
1216 g_variant_new("(s)", &file_path));
1218 new_auth_info = g_malloc0(sizeof(bt_auth_info_t));
1220 new_auth_info->file_size = agent_info.auth_info->file_size;
1221 new_auth_info->file_path = g_strdup(file_path);
1222 new_auth_info->filename = g_strdup(filename);
1223 new_auth_info->device_name = g_strdup(agent_info.auth_info->device_name);
1224 new_auth_info->transfer_path = g_strdup(agent_info.auth_info->transfer_path);
1225 new_auth_info->address = g_strdup(agent_info.auth_info->address);
1226 memcpy(new_auth_info->contact_auth_info, agent_info.auth_info->contact_auth_info, 5);
1228 __bt_free_auth_info(agent_info.auth_info);
1230 agent_info.auth_info = new_auth_info;
1232 return BLUETOOTH_ERROR_NONE;
1235 void _bt_obex_server_reply_accept(void)
1237 GVariant *param = NULL;
1238 bt_session_info_t *session_info = NULL;
1239 int result = BLUETOOTH_ERROR_NONE;
1240 param = g_variant_new("(istss)", result,
1241 agent_info.auth_info->filename,
1242 agent_info.auth_info->file_size,
1243 agent_info.auth_info->address,
1244 agent_info.auth_info->device_name);
1245 BT_INFO("Send Obex Authorize");
1246 _bt_send_event(BT_OPP_SERVER_EVENT, BLUETOOTH_EVENT_OBEX_SERVER_TRANSFER_AUTHORIZE, param);
1248 session_info = __bt_find_session_by_path(agent_info.auth_info->transfer_path);
1250 if (NULL == session_info)
1251 BT_ERR("Couldn't get the session info from the list");
1253 session_info->authorized = TRUE;
1256 int _bt_obex_server_reject_authorize(void)
1260 retv_if(agent_info.auth_info->reply_context == NULL,
1261 BLUETOOTH_ERROR_INTERNAL);
1263 g_error = g_error_new(__bt_obex_error_quark(),
1264 BT_OBEX_AGENT_ERROR_CANCEL,
1267 g_dbus_method_invocation_return_gerror(agent_info.auth_info->reply_context,
1269 g_error_free(g_error);
1271 __bt_free_auth_info(agent_info.auth_info);
1272 agent_info.auth_info = NULL;
1274 return BLUETOOTH_ERROR_NONE;
1277 int _bt_obex_server_set_destination_path(const char *dest_path,
1280 bt_server_info_t *server_info;
1281 BT_CHECK_PARAMETER(dest_path, return);
1284 dst_path = __bt_transfer_folder_path((char *)dest_path);
1288 dp = opendir(dst_path);
1291 BT_ERR("The directory does not exist");
1293 return BLUETOOTH_ERROR_INVALID_PARAM;
1298 if (is_native == TRUE)
1299 server_info = agent_info.native_server;
1301 server_info = agent_info.custom_server;
1304 BT_ERR("obex server info is NULL");
1306 return BLUETOOTH_ERROR_AGENT_DOES_NOT_EXIST;
1309 g_free(server_info->dest_path);
1310 server_info->dest_path = g_strdup(dst_path);
1313 return BLUETOOTH_ERROR_NONE;
1316 int _bt_obex_server_set_root(const char *root)
1318 GVariant *result = NULL;
1319 GError *g_error = NULL;
1320 GVariant *folder = NULL;
1321 char *string = "Root";
1324 BT_CHECK_PARAMETER(root, return);
1327 dst_root = __bt_transfer_folder_path((char *)root);
1329 if (!agent_info.proxy) {
1330 BT_ERR("obex agent_info proxy error");
1332 return BLUETOOTH_ERROR_INTERNAL;
1335 dp = opendir(dst_root);
1338 BT_ERR("The directory does not exist");
1340 return BLUETOOTH_ERROR_INVALID_PARAM;
1345 folder = g_variant_new_string(dst_root);
1346 result = g_dbus_proxy_call_sync(agent_info.proxy, "SetProperty",
1347 g_variant_new("(sv)", string, folder),
1348 G_DBUS_CALL_FLAGS_NONE,
1353 BT_ERR("SetProperty Fail: %s", g_error->message);
1354 g_error_free(g_error);
1356 return BLUETOOTH_ERROR_INTERNAL;
1360 g_variant_unref(result);
1363 return BLUETOOTH_ERROR_NONE;
1366 int _bt_obex_server_cancel_transfer(int transfer_id)
1368 bt_transfer_info_t *transfer = NULL;
1370 GVariant *result = NULL;
1373 transfer = __bt_find_transfer_by_id(transfer_id);
1375 retv_if(transfer == NULL, BLUETOOTH_ERROR_NOT_FOUND);
1376 proxy = __bt_get_transfer_proxy(transfer->path);
1378 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1380 result = g_dbus_proxy_call_sync(proxy, "Cancel", NULL,
1381 G_DBUS_CALL_FLAGS_NONE,
1382 DBUS_TIMEOUT, NULL, &err);
1384 BT_ERR("Dbus Err: %s", err->message);
1385 g_clear_error(&err);
1388 g_object_unref(proxy);
1391 g_variant_unref(result);
1393 return BLUETOOTH_ERROR_NONE;
1396 int _bt_obex_server_cancel_all_transfers(void)
1399 bt_transfer_info_t *transfer;
1401 for (l = transfers; l != NULL; l = l->next) {
1404 if (transfer == NULL)
1407 _bt_obex_server_cancel_transfer(transfer->transfer_id);
1410 return BLUETOOTH_ERROR_NONE;
1413 int _bt_obex_server_is_activated(gboolean *activated)
1415 BT_CHECK_PARAMETER(activated, return);
1417 if (agent_info.custom_server)
1422 return BLUETOOTH_ERROR_NONE;
1425 int _bt_obex_server_check_allocation(gboolean *allocation)
1427 BT_CHECK_PARAMETER(allocation, return);
1429 if (agent_info.native_server || agent_info.custom_server)
1432 *allocation = FALSE;
1434 return BLUETOOTH_ERROR_NONE;
1437 int _bt_obex_server_check_termination(char *sender)
1439 BT_CHECK_PARAMETER(sender, return);
1441 if (agent_info.native_server) {
1442 if (g_strcmp0(sender, agent_info.native_server->sender) == 0) {
1443 _bt_obex_server_deallocate(agent_info.native_server->app_pid,
1448 if (agent_info.custom_server) {
1449 if (g_strcmp0(sender, agent_info.custom_server->sender) == 0) {
1450 _bt_obex_server_deallocate(agent_info.custom_server->app_pid,
1455 return BLUETOOTH_ERROR_NONE;
1458 int _bt_obex_server_is_receiving(gboolean *receiving)
1460 BT_CHECK_PARAMETER(receiving, return);
1462 if (transfers == NULL || g_slist_length(transfers) == 0)
1467 return BLUETOOTH_ERROR_NONE;
1470 void _bt_obex_server_set_pending_conn_auth_device_addr(const char *address)
1472 if (pending_auth_address)
1473 g_free(pending_auth_address);
1475 pending_auth_address = g_strdup(address);
1478 /* To support the BOT */
1479 int _bt_obex_server_accept_connection(int request_id)
1482 bt_address_t bd_addr;
1484 BT_INFO("address: %s", pending_auth_address);
1485 _bt_convert_addr_string_to_type(bd_addr.addr, pending_auth_address);
1486 res = device_reply_auth_request(&bd_addr, OPP_SERVICE_ID, TRUE, FALSE);
1487 g_free(pending_auth_address);
1488 pending_auth_address = NULL;
1489 if (res != OAL_STATUS_SUCCESS) {
1490 BT_ERR("device_reply_auth_request failed");
1491 return BLUETOOTH_ERROR_INTERNAL;
1494 agent_info.accept_id = request_id;
1496 return BLUETOOTH_ERROR_NONE;
1499 /* To support the BOT */
1500 int _bt_obex_server_reject_connection(void)
1503 bt_address_t bd_addr;
1505 BT_INFO("address: %s", pending_auth_address);
1506 _bt_convert_addr_string_to_type(bd_addr.addr, pending_auth_address);
1507 res = device_reply_auth_request(&bd_addr, OPP_SERVICE_ID, FALSE, FALSE);
1508 g_free(pending_auth_address);
1509 pending_auth_address = NULL;
1510 if (res != OAL_STATUS_SUCCESS) {
1511 BT_ERR("device_reply_auth_request failed");
1512 return BLUETOOTH_ERROR_INTERNAL;
1515 return BLUETOOTH_ERROR_NONE;
1518 int _bt_opp_get_server_progress(int transfer_id, guint8 *progress)
1520 bt_transfer_info_t *requested_transfer = NULL;
1521 requested_transfer = __bt_find_transfer_by_id(transfer_id);
1522 if (requested_transfer == NULL) {
1523 BT_ERR("No Matching Inbound transfer");
1524 return BLUETOOTH_ERROR_NOT_FOUND;
1527 *progress = (int)(((double)requested_transfer->progress /
1528 requested_transfer->file_size) * 100);
1530 BT_DBG("Percentage: %d", *progress);
1531 return BLUETOOTH_ERROR_NONE;
1534 gboolean _bt_obex_server_is_custom(void)
1536 return (agent_info.server_type == BT_CUSTOM_SERVER) ? TRUE : FALSE;