Apply tizen 3.0 based product patchsets
[platform/core/connectivity/bluetooth-frwk.git] / bt-service / bt-service-obex-server.c
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
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
7  *
8  *              http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  *
16  */
17
18 #include <stdio.h>
19 #include <glib.h>
20 #include <dlog.h>
21 #include <string.h>
22 #include <dirent.h>
23 #ifdef TIZEN_FEATURE_BT_DPM
24 #include "bt-service-dpm.h"
25 #endif
26
27 #include <vconf.h>
28
29 #include <gio/gio.h>
30
31 #include "bluetooth-api.h"
32 #include "bt-internal-types.h"
33
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"
40
41 #define DBUS_TIMEOUT 20 * 1000 /* 20 Seconds */
42 #define BT_OBEX_SERVER_AGENT_PATH "/org/obex/server_agent"
43
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"
47
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
51
52
53 typedef struct {
54         char *filename;
55         char *file_path;
56         char *path;
57         char *type;
58         char *device_name;
59         int transfer_id;
60         gint64 file_size;
61         gint64 progress;
62         char *address;
63 } bt_transfer_info_t;
64
65 typedef struct {
66         GDBusMethodInvocation *reply_context;
67         guint64 file_size;
68         char *filename;
69         char *file_path;
70         char *device_name;
71         char *transfer_path;
72         char *address;
73         unsigned char contact_auth_info[5];
74 } bt_auth_info_t;
75
76 typedef struct {
77         char *dest_path;
78         char *sender;
79         int app_pid;
80 } bt_server_info_t;
81
82 typedef struct {
83         GDBusProxy *proxy;
84         int server_type;
85         int accept_id;
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;
90
91 typedef struct {
92         char *path;
93         char *address;
94         gboolean authorized;
95 } bt_session_info_t;
96
97 static GSList *transfers;
98 static bt_obex_agent_info_t agent_info;
99 static GSList *session_list = NULL;
100
101 static bt_session_info_t *__bt_find_session_by_path(char *transfer_path)
102 {
103         GSList *l;
104         bt_session_info_t *session;
105
106         retv_if(transfer_path == NULL, NULL);
107
108         for (l = session_list; l != NULL; l = l->next) {
109                 session = l->data;
110
111                 if (session == NULL)
112                         continue;
113
114                 if (g_strcmp0(session->path, transfer_path) == 0)
115                         return session;
116         }
117
118         return NULL;
119 }
120
121 static GQuark __bt_obex_error_quark(void)
122 {
123         static GQuark quark = 0;
124         if (!quark)
125                 quark = g_quark_from_static_string("agent");
126
127         return quark;
128 }
129
130 static bt_transfer_info_t *__bt_find_transfer_by_id(int transfer_id)
131 {
132         GSList *l;
133         bt_transfer_info_t *transfer;
134
135         for (l = transfers; l != NULL; l = l->next) {
136                 transfer = l->data;
137
138                 if (transfer == NULL)
139                         continue;
140
141                 if (transfer->transfer_id == transfer_id)
142                         return transfer;
143         }
144
145         return NULL;
146 }
147
148 bt_transfer_info_t *__bt_find_transfer_by_address(const char *address)
149 {
150         BT_DBG("+");
151         GSList *l;
152         bt_transfer_info_t *transfer;
153
154         retv_if(address == NULL, NULL);
155
156         for (l = transfers; l != NULL; l = l->next) {
157                 transfer = l->data;
158
159                 if (transfer == NULL)
160                         continue;
161
162                 if (g_strcmp0(transfer->address, address) == 0)
163                         return transfer;
164         }
165         BT_DBG("-");
166         return NULL;
167 }
168
169 static bt_transfer_info_t *__bt_find_transfer_by_path(const char *transfer_path)
170 {
171         GSList *l;
172         bt_transfer_info_t *transfer;
173
174         retv_if(transfer_path == NULL, NULL);
175
176         for (l = transfers; l != NULL; l = l->next) {
177                 transfer = l->data;
178
179                 if (transfer == NULL)
180                         continue;
181
182                 if (g_strcmp0(transfer->path, transfer_path) == 0)
183                         return transfer;
184         }
185
186         return NULL;
187 }
188
189 static void __bt_free_server_info(bt_server_info_t *server_info)
190 {
191         ret_if(server_info == NULL);
192
193         g_free(server_info->sender);
194         g_free(server_info->dest_path);
195         g_free(server_info);
196 }
197
198 static void __bt_free_auth_info(bt_auth_info_t *auto_info)
199 {
200         ret_if(auto_info == NULL);
201
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);
206         g_free(auto_info);
207 }
208
209 static void __bt_free_transfer_info(bt_transfer_info_t *transfer_info)
210 {
211         ret_if(transfer_info == NULL);
212
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);
220 }
221
222 void _bt_obex_check_pending_transfer(const char *address)
223 {
224         BT_DBG("+");
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,
231                                         transfer_info->type,
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,
240                         param);
241                 transfers = g_slist_remove(transfers, transfer_info);
242                 __bt_free_transfer_info(transfer_info);
243         }
244         BT_DBG("-");
245 }
246
247 static char *__bt_get_remote_device_name(const char *bdaddress)
248 {
249         char *device_path = NULL;
250         const gchar *name = NULL;
251         gchar *dev_name = NULL;
252         gsize name_len = 0;
253         GVariant *result = NULL;
254         GError *err = NULL;
255         GDBusProxy *device_proxy;
256         GDBusConnection *conn;
257
258         retv_if(bdaddress == NULL, NULL);
259
260         device_path = _bt_get_device_object_path((char *)bdaddress);
261         retv_if(device_path == NULL, NULL);
262
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,
267                                                 NULL, BT_BLUEZ_NAME,
268                                                 device_path,
269                                                 BT_PROPERTIES_INTERFACE,
270                                                 NULL, &err);
271
272         g_free(device_path);
273         retv_if(device_proxy == NULL, NULL);
274
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);
278         if (err) {
279                 BT_ERR("DBus Error : %s", err->message);
280                 g_clear_error(&err);
281         } else {
282                 GVariant *value;
283                 g_variant_get(result, "(v)", &value);
284                 name = g_variant_get_string(value, &name_len);
285                 INFO_SECURE("Alias Name [%s]", name);
286                 if (name_len)
287                         dev_name = g_strdup(name);
288                 g_variant_unref(value);
289                 g_variant_unref(result);
290         }
291
292         if (name_len == 0) {
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);
296                 if (err) {
297                         ERR("DBus Error : %s", err->message);
298                         g_clear_error(&err);
299                 } else {
300                         GVariant *value;
301                         g_variant_get(result, "(v)", &value);
302                         name = g_variant_get_string(value, &name_len);
303                         INFO_SECURE("Name = %s", name);
304                         if (name_len)
305                                 dev_name = g_strdup(name);
306                         g_variant_unref(value);
307                         g_variant_unref(result);
308                 }
309         }
310
311         g_object_unref(device_proxy);
312         return dev_name;
313 }
314
315 static void __bt_get_remote_device_name_authinfo(const char *bdaddress,
316                                         char **device_name, unsigned char *auth_info)
317 {
318         char *device_path = NULL;
319         char *name = NULL;
320         gboolean is_alias_set;
321         GVariant *value;
322         GVariant *result = NULL;
323         GError *err = NULL;
324         GDBusProxy *device_proxy;
325         GDBusConnection *conn;
326
327         ret_if(bdaddress == NULL);
328
329         device_path = _bt_get_device_object_path((char *)bdaddress);
330         ret_if(device_path == NULL);
331
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,
336                                                 NULL, BT_BLUEZ_NAME,
337                                                 device_path,
338                                                 BT_PROPERTIES_INTERFACE,
339                                                 NULL, &err);
340
341         g_free(device_path);
342         ret_if(device_proxy == NULL);
343
344         result = g_dbus_proxy_call_sync(device_proxy, "GetAll",
345                         g_variant_new("(s)", BT_DEVICE_INTERFACE),
346                         G_DBUS_CALL_FLAGS_NONE,
347                         DBUS_TIMEOUT, NULL,
348                         &err);
349         if (err) {
350                 BT_ERR("DBus Error : %s", err->message);
351                 g_clear_error(&err);
352                 return;
353         }
354         if (result == NULL) {
355                 BT_ERR("g_dbus_proxy_call_sync function return NULL");
356                 return;
357         }
358         g_variant_get(result, "(@a{sv})", &value);
359
360         if (value) {
361                 GVariant *temp_value = g_variant_lookup_value(value, "Alias",
362                         G_VARIANT_TYPE_STRING);
363                 g_variant_get(temp_value, "s", &name);
364                 if (temp_value)
365                         g_variant_unref(temp_value);
366
367                 if (name != NULL)
368                         DBG_SECURE("Alias Name [%s]", name);
369                 else {
370                         temp_value = g_variant_lookup_value(value, "Name", G_VARIANT_TYPE_STRING);
371                         g_variant_get(temp_value, "s", &name);
372                         if (temp_value)
373                                 g_variant_unref(temp_value);
374                         DBG_SECURE("Name = %s", name);
375                 }
376                 temp_value = g_variant_lookup_value(value, "IsAliasSet", G_VARIANT_TYPE_BOOLEAN);
377                 if (temp_value) {
378                         is_alias_set = g_variant_get_boolean(temp_value);
379                         g_variant_unref(temp_value);
380                 } else {
381                         is_alias_set = FALSE;
382                 }
383
384                 if (is_alias_set == FALSE)
385                         __bt_get_auth_info(value, (char *)auth_info);
386         }
387         g_variant_unref(result);
388         g_object_unref(device_proxy);
389
390         *device_name = g_strdup(name);
391         g_free(name);
392         return;
393 }
394
395 static int __bt_get_transfer_id(const char *path)
396 {
397         char *tmp = NULL;
398         if (path == NULL)
399                 return -1;
400
401         tmp = strrchr(path, 'r') + 1;
402         retv_if(tmp == NULL, -1);
403
404         return atoi(tmp);
405 }
406
407 static GDBusProxy *__bt_get_transfer_proxy(const char *transfer_path)
408 {
409         GDBusConnection *conn;
410         GDBusProxy *proxy;
411         GError *err = NULL;
412
413         conn = _bt_gdbus_get_system_gconn();
414         retv_if(conn == NULL, NULL);
415
416         proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
417                                         NULL, BT_OBEX_SERVICE_NAME,
418                                         transfer_path,
419                                         BT_OBEX_TRANSFER_INTERFACE,
420                                         NULL, &err);
421
422         if (proxy == NULL && err) {
423                 BT_ERR("Error : %s", err->message);
424                 g_clear_error(&err);
425                 return NULL;
426         }
427
428         return proxy;
429 }
430
431 static GDBusProxy *__bt_get_transfer_properties_proxy(const char *transfer_path)
432 {
433         GDBusConnection *conn;
434         GDBusProxy *proxy;
435         GError *err = NULL;
436         conn = _bt_gdbus_get_system_gconn();
437         retv_if(conn == NULL, NULL);
438
439         proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
440                                         NULL, BT_OBEX_SERVICE_NAME,
441                                         transfer_path,
442                                         BT_PROPERTIES_INTERFACE,
443                                         NULL, &err);
444         if (proxy == NULL && err) {
445                 BT_ERR("Error : %s", err->message);
446                 g_clear_error(&err);
447                 return NULL;
448         }
449         return proxy;
450 }
451
452 static int __bt_get_transfer_properties(bt_transfer_info_t *transfer_info,
453                                         const char *transfer_path)
454 {
455         GDBusProxy *transfer_proxy;
456         GVariant *result = NULL;
457         GError *err = NULL;
458         GVariantIter *iter = NULL;
459         BT_CHECK_PARAMETER(transfer_info, return);
460         BT_CHECK_PARAMETER(transfer_path, return);
461
462         transfer_proxy = __bt_get_transfer_properties_proxy(transfer_path);
463
464         retv_if(transfer_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
465
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,
469                         DBUS_TIMEOUT, NULL,
470                         &err);
471
472         if (err) {
473                 BT_ERR("DBus Error : %s", err->message);
474                 g_clear_error(&err);
475                 goto fail;
476         }
477         if (result == NULL) {
478                 BT_ERR("g_dbus_proxy_call_sync function return NULL");
479                 goto fail;
480         }
481
482         g_variant_get(result, "(a{sv})", &iter);
483         g_variant_unref(result);
484         if (iter) {
485                 const gchar *key;
486                 GVariant *val;
487                 gsize len = 0;
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);
502                         }
503                 }
504                 g_variant_iter_free(iter);
505
506                 if (transfer_info->address == NULL)
507                         goto fail;
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);
512
513                 if (transfer_info->type == NULL)
514                         goto fail;
515
516                 transfer_info->path = g_strdup(transfer_path);
517         }
518
519         g_object_unref(transfer_proxy);
520         return BLUETOOTH_ERROR_NONE;
521
522 fail:
523         g_object_unref(transfer_proxy);
524         return BLUETOOTH_ERROR_INTERNAL;
525 }
526
527 static gboolean __bt_authorize_cb(GDBusMethodInvocation *context,
528                                         const char *path,
529                                         gpointer user_data)
530 {
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;
536         GVariant *ret;
537         GVariantIter *iter;
538         GVariant *param = NULL;
539         GError *err = NULL;
540         bt_session_info_t *session_info = NULL;
541 #ifdef TIZEN_FEATURE_BT_DPM
542         int value = DPM_BT_ERROR;
543 #endif
544
545         BT_DBG(" path [%s] \n", path);
546
547         transfer_properties_proxy = __bt_get_transfer_properties_proxy(path);
548
549         retv_if(transfer_properties_proxy == NULL, FALSE);
550
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,
554                         DBUS_TIMEOUT, NULL,
555                         &err);
556         if (err) {
557                 BT_ERR("DBus Error : %s", err->message);
558                 g_clear_error(&err);
559                 return FALSE;
560         }
561         if (ret == NULL) {
562                 BT_ERR("g_dbus_proxy_call_sync function return NULL");
563                 return FALSE;
564         }
565         g_variant_get(ret, "(a{sv})", &iter);
566         g_variant_unref(ret);
567         if (iter == NULL) {
568                 g_object_unref(transfer_properties_proxy);
569                 return FALSE;
570         }
571
572         __bt_free_auth_info(agent_info.auth_info);
573
574         agent_info.auth_info = g_malloc(sizeof(bt_auth_info_t));
575
576         memset(agent_info.auth_info, 0, sizeof(bt_auth_info_t));
577
578         agent_info.auth_info->reply_context = context;
579
580         agent_info.auth_info->transfer_path = g_strdup(path);
581
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();
587                 return FALSE;
588         }
589 #endif
590         if (iter) {
591                 const gchar *key;
592                 GVariant *val;
593                 gsize len = 0;
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);
601                 }
602                 g_variant_iter_free(iter);
603         }
604
605         __bt_get_remote_device_name_authinfo(bdaddress, &device_name, auth_info);
606
607         if (!device_name)
608                 device_name = g_strdup(bdaddress);
609
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);
613
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);
621         }
622
623         g_object_unref(transfer_properties_proxy);
624         g_free(bdaddress);
625
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);
629                 return TRUE;
630         }
631
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);
636         } else {
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);
644         }
645
646         return TRUE;
647 }
648
649 void _bt_obex_transfer_started(const char *transfer_path)
650 {
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;
657         int i = 0;
658
659         BT_DBG("%s", transfer_path);
660
661         transfer_info = g_malloc0(sizeof(bt_transfer_info_t));
662
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);
673
674         } else {
675                 if (__bt_get_transfer_properties(transfer_info, transfer_path) < 0) {
676                         BT_ERR("Get Properties failed");
677                         __bt_free_transfer_info(transfer_info);
678                         return;
679                 }
680                 agent_info.server_type = BT_FTP_SERVER;
681         }
682
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;
688                         return;
689                 }
690
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");
694                         goto done;
695                 }
696
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,
704                                         TRUE, NULL, NULL);
705                 }
706
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);
711         }
712 done:
713         transfers = g_slist_append(transfers, transfer_info);
714
715         BT_DBG("Transfer id %d", transfer_info->transfer_id);
716
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]);
721         }
722
723         param = g_variant_new("(isssstii(ay))", result,
724                                 transfer_info->device_name,
725                                 transfer_info->filename,
726                                 transfer_info->type,
727                                 transfer_info->address,
728                                 transfer_info->file_size,
729                                 transfer_info->transfer_id,
730                                 agent_info.server_type,
731                                 builder);
732
733         __bt_free_auth_info(agent_info.auth_info);
734         agent_info.auth_info = NULL;
735
736         g_variant_builder_unref(builder);
737
738         _bt_send_event(BT_OPP_SERVER_EVENT,
739                 BLUETOOTH_EVENT_OBEX_SERVER_TRANSFER_STARTED,
740                 param);
741 }
742
743 void _bt_obex_transfer_progress(const char *transfer_path,
744                                         guint64 transferred)
745 {
746         BT_DBG("+");
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;
752
753         transfer_info = __bt_find_transfer_by_path(transfer_path);
754         ret_if(transfer_info == NULL);
755
756         current_progress = (int)(((gdouble)transferred /
757                         (gdouble)transfer_info->file_size) * 100);
758
759         previous_progress = (int)(((gdouble)transfer_info->progress /
760                         (gdouble)transfer_info->file_size) * 100);
761
762         if (current_progress == previous_progress) {
763                 BT_DBG("Same Percentage Value: Do not emit Signal");
764                 return;
765         }
766
767         transfer_info->progress = transferred;
768         param = g_variant_new("(isssstiii)", result,
769                                 transfer_info->filename,
770                                 transfer_info->type,
771                                 transfer_info->device_name,
772                                 transfer_info->address,
773                                 transfer_info->file_size,
774                                 transfer_info->transfer_id,
775                                 current_progress,
776                                 agent_info.server_type);
777         _bt_send_event(BT_OPP_SERVER_EVENT,
778                 BLUETOOTH_EVENT_OBEX_SERVER_TRANSFER_PROGRESS,
779                 param);
780         BT_DBG("-");
781 }
782
783 void _bt_obex_transfer_completed(const char *transfer_path, gboolean success)
784 {
785         bt_transfer_info_t *transfer_info;
786         GVariantBuilder *builder = NULL;
787         GVariant *param = NULL;
788         int result;
789         int i = 0;
790         BT_DBG("Transfer [%s] Success [%d] \n", transfer_path, success);
791
792         result = (success == TRUE) ? BLUETOOTH_ERROR_NONE
793                                 : BLUETOOTH_ERROR_CANCEL;
794
795         transfer_info = __bt_find_transfer_by_path(transfer_path);
796
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");
803                         return;
804                 }
805
806                 transfer_info = g_new0(bt_transfer_info_t, 1);
807
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);
816
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]);
820
821                 param = g_variant_new("(isssstii(ay))", result,
822                                         transfer_info->device_name,
823                                         transfer_info->filename,
824                                         transfer_info->type,
825                                         transfer_info->address,
826                                         transfer_info->file_size,
827                                         transfer_info->transfer_id,
828                                         agent_info.server_type,
829                                         builder);
830                 _bt_send_event(BT_OPP_SERVER_EVENT,
831                         BLUETOOTH_EVENT_OBEX_SERVER_TRANSFER_STARTED,
832                         param);
833                 g_variant_builder_unref(builder);
834         }
835         param = g_variant_new("(issssstii)", result,
836                                 transfer_info->filename,
837                                 transfer_info->type,
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,
846                 param);
847         transfers = g_slist_remove(transfers, transfer_info);
848         __bt_free_transfer_info(transfer_info);
849 }
850
851 void _bt_obex_transfer_connected(const char *obj_path)
852 {
853         BT_DBG("+");
854
855         int result = BLUETOOTH_ERROR_NONE;
856         GVariant *param = NULL;
857         bt_transfer_info_t *transfer_info = NULL;
858
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);
863
864         param = g_variant_new("(issi)", result, transfer_info->address,
865                         transfer_info->device_name, transfer_info->transfer_id);
866
867         _bt_send_event(BT_OPP_SERVER_EVENT,
868                 BLUETOOTH_EVENT_OBEX_SERVER_TRANSFER_CONNECTED,
869                 param);
870
871         __bt_free_transfer_info(transfer_info);
872         BT_DBG("-");
873 }
874
875 void _bt_obex_transfer_disconnected(char * obj_path)
876 {
877         BT_DBG("+");
878
879         int result = BLUETOOTH_ERROR_NONE;
880         GVariant *param = NULL;
881         bt_session_info_t *session = NULL;
882         int transfer_id = -1;
883
884         session = __bt_find_session_by_path(obj_path);
885         ret_if(session == NULL);
886
887         transfer_id = __bt_get_transfer_id(obj_path);
888         DBG_SECURE("transfer_id: [%d]", transfer_id);
889
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,
894                 param);
895         session_list = g_slist_remove(session_list, session);
896         g_free(session->address);
897         g_free(session->path);
898         g_free(session);
899         BT_DBG("-");
900 }
901
902 int _bt_register_obex_server(void)
903 {
904         GDBusConnection *g_conn;
905         GDBusProxy *manager_proxy;
906         GVariant *result = NULL;
907         GError *g_error = NULL;
908
909         /* Get the session bus. */
910         g_conn = _bt_gdbus_get_system_gconn();
911         retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
912
913         _bt_obex_agent_new(BT_OBEX_SERVER_AGENT_PATH);
914
915         _bt_obex_setup(BT_OBEX_SERVER_AGENT_PATH);
916
917         _bt_obex_set_authorize_cb(BT_OBEX_SERVER_AGENT_PATH,
918                                         __bt_authorize_cb, NULL);
919
920         manager_proxy = g_dbus_proxy_new_sync(g_conn, G_DBUS_PROXY_FLAGS_NONE,
921                                                 NULL, BT_OBEX_SERVICE,
922                                                 BT_OBEX_PATH,
923                                                 BT_OBEX_MANAGER,
924                                                 NULL, &g_error);
925
926         if (manager_proxy == NULL)
927                 return BLUETOOTH_ERROR_INTERNAL;
928
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,
932                                 DBUS_TIMEOUT, NULL,
933                                 &g_error);
934
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;
940         }
941
942         if (result)
943                 g_variant_unref(result);
944
945         agent_info.proxy = manager_proxy;
946
947         return BLUETOOTH_ERROR_NONE;
948 }
949
950 int _bt_unregister_obex_server(void)
951 {
952         GVariant *result = NULL;
953         GError *g_error = NULL;
954
955         retv_if(agent_info.proxy == NULL,
956                                 BLUETOOTH_ERROR_INTERNAL);
957
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,
961                                 DBUS_TIMEOUT, NULL,
962                                 &g_error);
963         if (g_error != NULL) {
964                 BT_ERR("Agent unregistration failed: %s", g_error->message);
965                 g_error_free(g_error);
966         }
967
968         if (result)
969                 g_variant_unref(result);
970
971         _bt_obex_agent_destroy(BT_OBEX_SERVER_AGENT_PATH);
972         g_object_unref(agent_info.proxy);
973         agent_info.proxy = NULL;
974
975         return BLUETOOTH_ERROR_NONE;
976 }
977
978 gboolean __bt_check_folder_path(const char *dest_path)
979 {
980         DIR *dp;
981
982         retv_if(dest_path == NULL, FALSE);
983
984         dp = opendir(dest_path);
985
986         if (dp == NULL) {
987                 BT_ERR("The directory does not exist");
988                 return FALSE;
989         }
990
991         closedir(dp);
992
993         return TRUE;
994 }
995
996 char *__bt_transfer_folder_path(char *dest_path)
997 {
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));
1001         else
1002                 snprintf(dst_path, BT_OBEX_PATH_MAX_LENGTH, "%s", dest_path);
1003
1004         BT_INFO("obex transfed path : %s", dst_path);
1005         return dst_path;
1006 }
1007
1008 int _bt_obex_server_allocate(char *sender, const char *dest_path, int app_pid, gboolean is_native)
1009 {
1010         BT_DBG("+");
1011
1012         char *dst_path;
1013         dst_path = __bt_transfer_folder_path((char *)dest_path);
1014
1015         if (__bt_check_folder_path(dst_path) == FALSE) {
1016                 g_free(dst_path);
1017                 return BLUETOOTH_ERROR_INVALID_PARAM;
1018         }
1019
1020         if (is_native == TRUE) {
1021                 if (agent_info.native_server) {
1022                         BT_ERR("obex native server busy");
1023                         g_free(dst_path);
1024                         return BLUETOOTH_ERROR_DEVICE_BUSY;
1025                 }
1026
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);
1034         } else {
1035                 if (agent_info.custom_server) {
1036                         BT_ERR("obex custom server busy");
1037                         g_free(dst_path);
1038                         return BLUETOOTH_ERROR_DEVICE_BUSY;
1039                 }
1040
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);
1048         }
1049
1050         g_free(dst_path);
1051         BT_DBG("-");
1052         return BLUETOOTH_ERROR_NONE;
1053 }
1054
1055 int _bt_obex_server_deallocate(int app_pid, gboolean is_native)
1056 {
1057         if (is_native == TRUE) {
1058                 retv_if(agent_info.native_server == NULL,
1059                                 BLUETOOTH_ERROR_AGENT_DOES_NOT_EXIST);
1060
1061                 retv_if(agent_info.native_server->app_pid != app_pid,
1062                                 BLUETOOTH_ERROR_ACCESS_DENIED);
1063
1064                 __bt_free_server_info(agent_info.native_server);
1065                 agent_info.native_server = NULL;
1066
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,
1071                                                         NULL, NULL, -1);
1072                 }
1073         } else {
1074                 retv_if(agent_info.custom_server == NULL,
1075                                 BLUETOOTH_ERROR_AGENT_DOES_NOT_EXIST);
1076
1077                 retv_if(agent_info.custom_server->app_pid != app_pid,
1078                                 BLUETOOTH_ERROR_ACCESS_DENIED);
1079
1080                 __bt_free_server_info(agent_info.custom_server);
1081                 agent_info.custom_server = NULL;
1082
1083                 _bt_unregister_osp_server_in_agent(BT_OBEX_SERVER, NULL);
1084
1085                 /* Change the control to native */
1086                 if (agent_info.native_server)
1087                         agent_info.server_type = BT_NATIVE_SERVER;
1088         }
1089
1090         return BLUETOOTH_ERROR_NONE;
1091 }
1092
1093 int _bt_obex_server_accept_authorize(const char *filename, gboolean is_native)
1094 {
1095         char file_path[BT_FILE_PATH_MAX] = { 0 };
1096         bt_server_info_t *server_info;
1097
1098         BT_CHECK_PARAMETER(filename, return);
1099
1100         retv_if(agent_info.auth_info == NULL, BLUETOOTH_ERROR_INTERNAL);
1101
1102         retv_if(agent_info.auth_info->reply_context == NULL,
1103                                 BLUETOOTH_ERROR_INTERNAL);
1104
1105         if (is_native == TRUE)
1106                 server_info = agent_info.native_server;
1107         else
1108                 server_info = agent_info.custom_server;
1109
1110         retv_if(server_info == NULL, BLUETOOTH_ERROR_INTERNAL);
1111
1112         if (server_info->dest_path != NULL)
1113                 snprintf(file_path, sizeof(file_path), "%s/%s",
1114                         server_info->dest_path, filename);
1115         else
1116                 snprintf(file_path, sizeof(file_path), "%s", filename);
1117
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);
1124
1125         return BLUETOOTH_ERROR_NONE;
1126 }
1127
1128 void _bt_obex_server_reply_accept(void)
1129 {
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);
1140
1141         session_info = __bt_find_session_by_path(agent_info.auth_info->transfer_path);
1142
1143         if (NULL == session_info)
1144                 BT_ERR("Couldn't get the session info from the list");
1145         else
1146                 session_info->authorized = TRUE;
1147 }
1148
1149 int _bt_obex_server_reject_authorize(void)
1150 {
1151         GError *g_error;
1152
1153         retv_if(agent_info.auth_info->reply_context == NULL,
1154                                 BLUETOOTH_ERROR_INTERNAL);
1155
1156         g_error = g_error_new(__bt_obex_error_quark(),
1157                         BT_OBEX_AGENT_ERROR_CANCEL,
1158                         "CancelledByUser");
1159
1160         g_dbus_method_invocation_return_gerror(agent_info.auth_info->reply_context,
1161                         g_error);
1162         g_error_free(g_error);
1163
1164         __bt_free_auth_info(agent_info.auth_info);
1165         agent_info.auth_info = NULL;
1166
1167         return BLUETOOTH_ERROR_NONE;
1168 }
1169
1170 int _bt_obex_server_set_destination_path(const char *dest_path,
1171                                                 gboolean is_native)
1172 {
1173         bt_server_info_t *server_info;
1174         BT_CHECK_PARAMETER(dest_path, return);
1175
1176         char *dst_path;
1177         dst_path = __bt_transfer_folder_path((char *)dest_path);
1178
1179         DIR *dp = NULL;
1180
1181         dp = opendir(dst_path);
1182
1183         if (dp == NULL) {
1184                 BT_ERR("The directory does not exist");
1185                 g_free(dst_path);
1186                 return BLUETOOTH_ERROR_INVALID_PARAM;
1187         }
1188
1189         closedir(dp);
1190
1191         if (is_native == TRUE)
1192                 server_info = agent_info.native_server;
1193         else
1194                 server_info = agent_info.custom_server;
1195
1196         if (!server_info) {
1197                 BT_ERR("obex server info is NULL");
1198                 g_free(dst_path);
1199                 return BLUETOOTH_ERROR_AGENT_DOES_NOT_EXIST;
1200         }
1201
1202         g_free(server_info->dest_path);
1203         server_info->dest_path = g_strdup(dst_path);
1204
1205         g_free(dst_path);
1206         return BLUETOOTH_ERROR_NONE;
1207 }
1208
1209 int _bt_obex_server_set_root(const char *root)
1210 {
1211         GVariant *result = NULL;
1212         GError *g_error = NULL;
1213         GVariant *folder = NULL;
1214         char *string = "Root";
1215         DIR *dp = NULL;
1216
1217         BT_CHECK_PARAMETER(root, return);
1218
1219         char *dst_root;
1220         dst_root = __bt_transfer_folder_path((char *)root);
1221
1222         if (!agent_info.proxy) {
1223                 BT_ERR("obex agent_info proxy error");
1224                 g_free(dst_root);
1225                 return BLUETOOTH_ERROR_INTERNAL;
1226         }
1227
1228         dp = opendir(dst_root);
1229
1230         if (dp == NULL) {
1231                 BT_ERR("The directory does not exist");
1232                 g_free(dst_root);
1233                 return BLUETOOTH_ERROR_INVALID_PARAM;
1234         }
1235
1236         closedir(dp);
1237
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,
1242                         DBUS_TIMEOUT, NULL,
1243                         &g_error);
1244
1245         if (g_error) {
1246                 BT_ERR("SetProperty Fail: %s", g_error->message);
1247                 g_error_free(g_error);
1248                 g_free(dst_root);
1249                 return BLUETOOTH_ERROR_INTERNAL;
1250         }
1251
1252         if (result)
1253                 g_variant_unref(result);
1254
1255         g_free(dst_root);
1256         return BLUETOOTH_ERROR_NONE;
1257 }
1258
1259 int _bt_obex_server_cancel_transfer(int transfer_id)
1260 {
1261         bt_transfer_info_t *transfer = NULL;
1262         GDBusProxy *proxy;
1263         GVariant *result = NULL;
1264         GError *err = NULL;
1265         BT_DBG("+");
1266         transfer = __bt_find_transfer_by_id(transfer_id);
1267
1268         retv_if(transfer == NULL, BLUETOOTH_ERROR_NOT_FOUND);
1269         proxy = __bt_get_transfer_proxy(transfer->path);
1270
1271         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1272
1273         result = g_dbus_proxy_call_sync(proxy, "Cancel", NULL,
1274                 G_DBUS_CALL_FLAGS_NONE,
1275                 DBUS_TIMEOUT, NULL, &err);
1276         if (err) {
1277                 BT_ERR("Dbus Err: %s", err->message);
1278                 g_clear_error(&err);
1279         }
1280
1281         g_object_unref(proxy);
1282
1283         if (result)
1284                 g_variant_unref(result);
1285
1286         return BLUETOOTH_ERROR_NONE;
1287 }
1288
1289 int _bt_obex_server_cancel_all_transfers(void)
1290 {
1291         GSList *l;
1292         bt_transfer_info_t *transfer;
1293
1294         for (l = transfers; l != NULL; l = l->next) {
1295                 transfer = l->data;
1296
1297                 if (transfer == NULL)
1298                         continue;
1299
1300                 _bt_obex_server_cancel_transfer(transfer->transfer_id);
1301         }
1302
1303         return BLUETOOTH_ERROR_NONE;
1304 }
1305
1306 int _bt_obex_server_is_activated(gboolean *activated)
1307 {
1308         BT_CHECK_PARAMETER(activated, return);
1309
1310         if (agent_info.custom_server)
1311                 *activated = TRUE;
1312         else
1313                 *activated = FALSE;
1314
1315         return BLUETOOTH_ERROR_NONE;
1316 }
1317
1318 int _bt_obex_server_check_allocation(gboolean *allocation)
1319 {
1320         BT_CHECK_PARAMETER(allocation, return);
1321
1322         if (agent_info.native_server || agent_info.custom_server)
1323                 *allocation = TRUE;
1324         else
1325                 *allocation = FALSE;
1326
1327         return BLUETOOTH_ERROR_NONE;
1328 }
1329
1330 int _bt_obex_server_check_termination(char *sender)
1331 {
1332         BT_CHECK_PARAMETER(sender, return);
1333
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,
1337                                                 TRUE);
1338                 }
1339         }
1340
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,
1344                                                 FALSE);
1345                 }
1346         }
1347
1348         return BLUETOOTH_ERROR_NONE;
1349 }
1350
1351 int _bt_obex_server_is_receiving(gboolean *receiving)
1352 {
1353         BT_CHECK_PARAMETER(receiving, return);
1354
1355         if (transfers == NULL || g_slist_length(transfers) == 0)
1356                 *receiving = FALSE;
1357         else
1358                 *receiving = TRUE;
1359
1360         return BLUETOOTH_ERROR_NONE;
1361 }
1362
1363 gboolean __bt_obex_server_accept_timeout_cb(gpointer user_data)
1364 {
1365         request_info_t *req_info;
1366         GVariant *out_param1 = NULL;
1367         int result = BLUETOOTH_ERROR_TIMEOUT;
1368
1369         /* Already reply in _bt_obex_transfer_started */
1370         retv_if(agent_info.accept_id == 0, FALSE);
1371
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");
1375                 return FALSE;
1376         }
1377
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,
1384                                 TRUE, NULL, NULL);
1385         }
1386
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);
1391
1392         return FALSE;
1393 }
1394
1395 /* To support the BOT  */
1396 int _bt_obex_server_accept_connection(int request_id)
1397 {
1398         if (!_bt_agent_reply_authorize(TRUE))
1399                 return BLUETOOTH_ERROR_INTERNAL;
1400
1401         agent_info.accept_id = request_id;
1402
1403         g_timeout_add(BT_SERVER_ACCEPT_TIMEOUT,
1404                         (GSourceFunc)__bt_obex_server_accept_timeout_cb,
1405                         NULL);
1406
1407         return BLUETOOTH_ERROR_NONE;
1408 }
1409
1410 /* To support the BOT  */
1411 int _bt_obex_server_reject_connection(void)
1412 {
1413         if (!_bt_agent_reply_authorize(FALSE))
1414                 return BLUETOOTH_ERROR_INTERNAL;
1415
1416         return BLUETOOTH_ERROR_NONE;
1417 }
1418
1419 int _bt_opp_get_server_progress(int transfer_id, guint8 *progress)
1420 {
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;
1426         }
1427
1428         *progress = (int)(((double)requested_transfer->progress /
1429                         requested_transfer->file_size) * 100);
1430
1431         BT_DBG("Percentage: %d", *progress);
1432         return BLUETOOTH_ERROR_NONE;
1433 }