Modify the pid and gid of bt-service to network_fw
[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         char *name = NULL;
251         GVariant *value;
252         GVariant *result = NULL;
253         GError *err = NULL;
254         GDBusProxy *device_proxy;
255         GDBusConnection *conn;
256
257         retv_if(bdaddress == NULL, NULL);
258
259         device_path = _bt_get_device_object_path((char *)bdaddress);
260         retv_if(device_path == NULL, NULL);
261
262         conn = _bt_gdbus_get_system_gconn();
263         retv_if(conn == NULL, NULL);
264         BT_INFO("Device_path %s", device_path);
265         device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
266                                                 NULL, BT_BLUEZ_NAME,
267                                                 device_path,
268                                                 BT_PROPERTIES_INTERFACE,
269                                                 NULL, &err);
270
271         g_free(device_path);
272         retv_if(device_proxy == NULL, NULL);
273
274         result = g_dbus_proxy_call_sync(device_proxy, "GetAll",
275                         g_variant_new("(s)", BT_DEVICE_INTERFACE),
276                         G_DBUS_CALL_FLAGS_NONE,
277                         DBUS_TIMEOUT, NULL,
278                         &err);
279         if (err) {
280                 BT_ERR("DBus Error : %s", err->message);
281                 g_clear_error(&err);
282                 return NULL;
283         }
284         if (result == NULL) {
285                 BT_ERR("g_dbus_proxy_call_sync function return NULL");
286                 return NULL;
287         }
288         g_variant_get(result, "(@a{sv})", &value);
289
290         if (value) {
291                 GVariant *temp_value = g_variant_lookup_value(value, "Alias",
292                         G_VARIANT_TYPE_STRING);
293                 g_variant_get(temp_value, "s", &name);
294                 if (temp_value)
295                         g_variant_unref(temp_value);
296
297                 if (name != NULL)
298                         DBG_SECURE("Alias Name [%s]", name);
299                 else {
300                         temp_value = g_variant_lookup_value(value, "Name", G_VARIANT_TYPE_STRING);
301                         g_variant_get(temp_value, "s", &name);
302                         if (temp_value)
303                                 g_variant_unref(temp_value);
304                         DBG_SECURE("Name = %s", name);
305                 }
306         }
307         g_variant_unref(result);
308         g_object_unref(device_proxy);
309         return name;
310 }
311
312 static void __bt_get_remote_device_name_authinfo(const char *bdaddress,
313                                         char **device_name, unsigned char *auth_info)
314 {
315         char *device_path = NULL;
316         char *name = NULL;
317         gboolean is_alias_set;
318         GVariant *value;
319         GVariant *result = NULL;
320         GError *err = NULL;
321         GDBusProxy *device_proxy;
322         GDBusConnection *conn;
323
324         ret_if(bdaddress == NULL);
325
326         device_path = _bt_get_device_object_path((char *)bdaddress);
327         ret_if(device_path == NULL);
328
329         conn = _bt_gdbus_get_system_gconn();
330         ret_if(conn == NULL);
331         BT_INFO("Device_path %s", device_path);
332         device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
333                                                 NULL, BT_BLUEZ_NAME,
334                                                 device_path,
335                                                 BT_PROPERTIES_INTERFACE,
336                                                 NULL, &err);
337
338         g_free(device_path);
339         ret_if(device_proxy == NULL);
340
341         result = g_dbus_proxy_call_sync(device_proxy, "GetAll",
342                         g_variant_new("(s)", BT_DEVICE_INTERFACE),
343                         G_DBUS_CALL_FLAGS_NONE,
344                         DBUS_TIMEOUT, NULL,
345                         &err);
346         if (err) {
347                 BT_ERR("DBus Error : %s", err->message);
348                 g_clear_error(&err);
349                 return;
350         }
351         if (result == NULL) {
352                 BT_ERR("g_dbus_proxy_call_sync function return NULL");
353                 return;
354         }
355         g_variant_get(result, "(@a{sv})", &value);
356
357         if (value) {
358                 GVariant *temp_value = g_variant_lookup_value(value, "Alias",
359                         G_VARIANT_TYPE_STRING);
360                 g_variant_get(temp_value, "s", &name);
361                 if (temp_value)
362                         g_variant_unref(temp_value);
363
364                 if (name != NULL)
365                         DBG_SECURE("Alias Name [%s]", name);
366                 else {
367                         temp_value = g_variant_lookup_value(value, "Name", G_VARIANT_TYPE_STRING);
368                         g_variant_get(temp_value, "s", &name);
369                         if (temp_value)
370                                 g_variant_unref(temp_value);
371                         DBG_SECURE("Name = %s", name);
372                 }
373                 temp_value = g_variant_lookup_value(value, "IsAliasSet", G_VARIANT_TYPE_BOOLEAN);
374                 if (temp_value) {
375                         is_alias_set = g_variant_get_boolean(temp_value);
376                         g_variant_unref(temp_value);
377                 } else {
378                         is_alias_set = FALSE;
379                 }
380
381                 if (is_alias_set == FALSE)
382                         __bt_get_auth_info(value, (char *)auth_info);
383         }
384         g_variant_unref(result);
385         g_object_unref(device_proxy);
386
387         *device_name = g_strdup(name);
388         g_free(name);
389         return;
390 }
391
392 static int __bt_get_transfer_id(const char *path)
393 {
394         char *tmp = NULL;
395         if (path == NULL)
396                 return -1;
397
398         tmp = strrchr(path, 'r') + 1;
399         retv_if(tmp == NULL, -1);
400
401         return atoi(tmp);
402 }
403
404 static GDBusProxy *__bt_get_transfer_proxy(const char *transfer_path)
405 {
406         GDBusConnection *conn;
407         GDBusProxy *proxy;
408         GError *err = NULL;
409
410         conn = _bt_gdbus_get_system_gconn();
411         retv_if(conn == NULL, NULL);
412
413         proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
414                                         NULL, BT_OBEX_SERVICE_NAME,
415                                         transfer_path,
416                                         BT_OBEX_TRANSFER_INTERFACE,
417                                         NULL, &err);
418
419         if (err) {
420                 BT_ERR("Error : %s", err->message);
421                 g_clear_error(&err);
422                 return NULL;
423         }
424
425         return proxy;
426 }
427
428 static GDBusProxy *__bt_get_transfer_properties_proxy(const char *transfer_path)
429 {
430         GDBusConnection *conn;
431         GDBusProxy *proxy;
432         GError *err = NULL;
433         conn = _bt_gdbus_get_system_gconn();
434         retv_if(conn == NULL, NULL);
435
436         proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
437                                         NULL, BT_OBEX_SERVICE_NAME,
438                                         transfer_path,
439                                         BT_PROPERTIES_INTERFACE,
440                                         NULL, &err);
441         if (err) {
442                 BT_ERR("Error : %s", err->message);
443                 g_clear_error(&err);
444                 return NULL;
445         }
446         return proxy;
447 }
448
449 static int __bt_get_transfer_properties(bt_transfer_info_t *transfer_info,
450                                         const char *transfer_path)
451 {
452         GDBusProxy *transfer_proxy;
453         GVariant *result = NULL;
454         GError *err = NULL;
455         GVariantIter *iter = NULL;
456         BT_CHECK_PARAMETER(transfer_info, return);
457         BT_CHECK_PARAMETER(transfer_path, return);
458
459         transfer_proxy = __bt_get_transfer_properties_proxy(transfer_path);
460
461         retv_if(transfer_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
462
463         result = g_dbus_proxy_call_sync(transfer_proxy, "GetAll",
464                         g_variant_new("(s)", BT_OBEX_TRANSFER_INTERFACE),
465                         G_DBUS_CALL_FLAGS_NONE,
466                         DBUS_TIMEOUT, NULL,
467                         &err);
468
469         if (err) {
470                 BT_ERR("DBus Error : %s", err->message);
471                 g_clear_error(&err);
472                 goto fail;
473         }
474         if (result == NULL) {
475                 BT_ERR("g_dbus_proxy_call_sync function return NULL");
476                 goto fail;
477         }
478
479         g_variant_get(result, "(a{sv})", &iter);
480         g_variant_unref(result);
481         if (iter) {
482                 const gchar *key;
483                 GVariant *val;
484                 gsize len = 0;
485                 while (g_variant_iter_loop(iter, "{sv}", &key, &val)) {
486                         if (g_strcmp0(key, "Operation") == 0) {
487                                 transfer_info->type = g_variant_dup_string(val, &len);
488                         } else if (g_strcmp0(key, "Name") == 0) {
489                                 transfer_info->filename = g_variant_dup_string(val, &len);
490                         } else if (g_strcmp0(key, "Size") == 0) {
491                                 transfer_info->file_size = g_variant_get_uint64(val);
492                         } else if (g_strcmp0(key, "Address") == 0) {
493                                 transfer_info->address = g_variant_dup_string(val, &len);
494                                 BT_INFO("addressss %s", transfer_info->address);
495                         } else if (g_strcmp0(key, "Filename") == 0) {
496                                 transfer_info->file_path = g_variant_dup_string(val, &len);
497                                 if (!transfer_info->file_path)
498                                         transfer_info->file_path = g_strdup(transfer_info->filename);
499                         }
500                 }
501                 g_variant_iter_free(iter);
502
503                 if (transfer_info->address == NULL)
504                         goto fail;
505                 transfer_info->device_name = __bt_get_remote_device_name(transfer_info->address);
506                 transfer_info->transfer_id = __bt_get_transfer_id(transfer_path);
507                 if (!transfer_info->device_name)
508                         transfer_info->device_name = g_strdup(transfer_info->address);
509
510                 if (transfer_info->type == NULL)
511                         goto fail;
512
513                 transfer_info->path = g_strdup(transfer_path);
514         }
515
516         g_object_unref(transfer_proxy);
517         return BLUETOOTH_ERROR_NONE;
518
519 fail:
520         g_object_unref(transfer_proxy);
521         return BLUETOOTH_ERROR_INTERNAL;
522 }
523
524 static gboolean __bt_authorize_cb(GDBusMethodInvocation *context,
525                                         const char *path,
526                                         gpointer user_data)
527 {
528         char *device_name = NULL;
529         unsigned char auth_info[5] = {0, };
530         int result = BLUETOOTH_ERROR_NONE;
531         GDBusProxy *transfer_properties_proxy;
532         char * bdaddress = NULL;
533         GVariant *ret;
534         GVariantIter *iter;
535         GVariant *param = NULL;
536         GError *err = NULL;
537         bt_session_info_t *session_info = NULL;
538 #ifdef TIZEN_FEATURE_BT_DPM
539         int value = DPM_BT_ERROR;
540 #endif
541
542         BT_DBG(" path [%s] \n", path);
543
544         transfer_properties_proxy = __bt_get_transfer_properties_proxy(path);
545
546         retv_if(transfer_properties_proxy == NULL, FALSE);
547
548         ret = g_dbus_proxy_call_sync(transfer_properties_proxy, "GetAll",
549                         g_variant_new("(s)", BT_OBEX_TRANSFER_INTERFACE),
550                         G_DBUS_CALL_FLAGS_NONE,
551                         DBUS_TIMEOUT, NULL,
552                         &err);
553         if (err) {
554                 BT_ERR("DBus Error : %s", err->message);
555                 g_clear_error(&err);
556                 return FALSE;
557         }
558         if (ret == NULL) {
559                 BT_ERR("g_dbus_proxy_call_sync function return NULL");
560                 return FALSE;
561         }
562         g_variant_get(ret, "(a{sv})", &iter);
563         g_variant_unref(ret);
564         if (iter == NULL) {
565                 g_object_unref(transfer_properties_proxy);
566                 return FALSE;
567         }
568
569         __bt_free_auth_info(agent_info.auth_info);
570
571         agent_info.auth_info = g_malloc(sizeof(bt_auth_info_t));
572
573         memset(agent_info.auth_info, 0, sizeof(bt_auth_info_t));
574
575         agent_info.auth_info->reply_context = context;
576
577         agent_info.auth_info->transfer_path = g_strdup(path);
578
579 #ifdef TIZEN_FEATURE_BT_DPM
580         _bt_dpm_get_allow_bluetooth_mode(&value);
581         if (value == DPM_BT_HANDSFREE_ONLY) {
582                 /* Free auth info in next function */
583                 _bt_obex_server_reject_authorize();
584                 return FALSE;
585         }
586 #endif
587         if (iter) {
588                 const gchar *key;
589                 GVariant *val;
590                 gsize len = 0;
591                 while (g_variant_iter_loop(iter, "{sv}", &key, &val)) {
592                         if (g_strcmp0(key, "Name") == 0)
593                                 agent_info.auth_info->filename = g_variant_dup_string(val, &len);
594                         else if (g_strcmp0(key, "Address") == 0)
595                                 bdaddress = g_variant_dup_string(val, &len);
596                         else if (g_strcmp0(key, "Size") == 0)
597                                 agent_info.auth_info->file_size = g_variant_get_uint64(val);
598                 }
599                 g_variant_iter_free(iter);
600         }
601
602         __bt_get_remote_device_name_authinfo(bdaddress, &device_name, auth_info);
603
604         if (!device_name)
605                 device_name = g_strdup(bdaddress);
606
607         agent_info.auth_info->address = g_strdup(bdaddress);
608         agent_info.auth_info->device_name = device_name;
609         memcpy(agent_info.auth_info->contact_auth_info, auth_info, 5);
610
611         session_info = __bt_find_session_by_path((char *)path);
612         if (NULL == session_info) {
613                 session_info = g_malloc0(sizeof(bt_session_info_t));
614                 session_info->path = g_strdup(path);
615                 session_info->address = g_strdup(bdaddress);
616                 session_info->authorized = FALSE;
617                 session_list = g_slist_append(session_list, session_info);
618         }
619
620         g_object_unref(transfer_properties_proxy);
621         g_free(bdaddress);
622
623         if (agent_info.server_type == BT_CUSTOM_SERVER) {
624                 /* No need to send the event */
625                 _bt_obex_server_accept_authorize(agent_info.auth_info->filename, FALSE);
626                 return TRUE;
627         }
628
629         if (session_info->authorized == FALSE) {
630                 if (headed_plugin_info->plugin_headed_enabled)
631                         headed_plugin_info->headed_plugin->bt_launch_system_popup(BT_AGENT_EVENT_EXCHANGE_REQUEST, device_name,
632                                         auth_info, NULL, NULL, BT_OBEX_SERVER_AGENT_PATH);
633         } else {
634                 param = g_variant_new("(istss)", result,
635                                 agent_info.auth_info->filename,
636                                 agent_info.auth_info->file_size,
637                                 agent_info.auth_info->address,
638                                 agent_info.auth_info->device_name);
639                 _bt_send_event(BT_OPP_SERVER_EVENT,
640                                 BLUETOOTH_EVENT_OBEX_SERVER_TRANSFER_AUTHORIZE, param);
641         }
642
643         return TRUE;
644 }
645
646 void _bt_obex_transfer_started(const char *transfer_path)
647 {
648         bt_transfer_info_t *transfer_info;
649         request_info_t *req_info;
650         GVariant *out_param1 = NULL;
651         GVariant *param = NULL;
652         GVariantBuilder *builder = NULL;
653         int result = BLUETOOTH_ERROR_NONE;
654         int i = 0;
655
656         BT_DBG("%s", transfer_path);
657
658         transfer_info = g_malloc0(sizeof(bt_transfer_info_t));
659
660         if (agent_info.auth_info != NULL
661              && g_strcmp0(transfer_path, agent_info.auth_info->transfer_path) == 0) {
662                 transfer_info->filename = g_strdup(agent_info.auth_info->filename);
663                 transfer_info->file_size = agent_info.auth_info->file_size;
664                 transfer_info->type = g_strdup(TRANSFER_PUT);
665                 transfer_info->path = g_strdup(agent_info.auth_info->transfer_path);
666                 transfer_info->device_name = g_strdup(agent_info.auth_info->device_name);
667                 transfer_info->transfer_id = __bt_get_transfer_id(transfer_path);
668                 transfer_info->file_path = agent_info.auth_info->file_path;
669                 transfer_info->address = g_strdup(agent_info.auth_info->address);
670
671         } else {
672                 if (__bt_get_transfer_properties(transfer_info, transfer_path) < 0) {
673                         BT_ERR("Get Properties failed");
674                         __bt_free_transfer_info(transfer_info);
675                         return;
676                 }
677                 agent_info.server_type = BT_FTP_SERVER;
678         }
679
680         if (agent_info.server_type == BT_CUSTOM_SERVER) {
681                 if (agent_info.custom_server == NULL) {
682                         __bt_free_transfer_info(transfer_info);
683                         __bt_free_auth_info(agent_info.auth_info);
684                         agent_info.auth_info = NULL;
685                         return;
686                 }
687
688                 req_info = _bt_get_request_info(agent_info.accept_id);
689                 if (req_info == NULL || req_info->context == NULL) {
690                         BT_ERR("info is NULL");
691                         goto done;
692                 }
693
694                 agent_info.accept_id = 0;
695                 result = BLUETOOTH_ERROR_NONE;
696                 GArray *g_out_param1 = NULL;
697                 g_out_param1 = g_array_new(FALSE, FALSE, sizeof(gchar));
698                 if (out_param1 == NULL) {
699                         out_param1 = g_variant_new_from_data((const GVariantType *)"ay",
700                                         g_out_param1->data, g_out_param1->len,
701                                         TRUE, NULL, NULL);
702                 }
703
704                 g_dbus_method_invocation_return_value(req_info->context,
705                                 g_variant_new("(iv)", result, out_param1));
706                 g_array_free(g_out_param1, TRUE);
707                 _bt_delete_request_list(req_info->req_id);
708         }
709 done:
710         transfers = g_slist_append(transfers, transfer_info);
711
712         BT_DBG("Transfer id %d", transfer_info->transfer_id);
713
714         builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
715         for (i = 0; i < 5; i++) {
716                 if (agent_info.auth_info)
717                         g_variant_builder_add(builder, "y", agent_info.auth_info->contact_auth_info[i]);
718         }
719
720         param = g_variant_new("(isssstii(ay))", result,
721                                 transfer_info->device_name,
722                                 transfer_info->filename,
723                                 transfer_info->type,
724                                 transfer_info->address,
725                                 transfer_info->file_size,
726                                 transfer_info->transfer_id,
727                                 agent_info.server_type,
728                                 builder);
729
730         __bt_free_auth_info(agent_info.auth_info);
731         agent_info.auth_info = NULL;
732
733         g_variant_builder_unref(builder);
734
735         _bt_send_event(BT_OPP_SERVER_EVENT,
736                 BLUETOOTH_EVENT_OBEX_SERVER_TRANSFER_STARTED,
737                 param);
738 }
739
740 void _bt_obex_transfer_progress(const char *transfer_path,
741                                         guint64 transferred)
742 {
743         BT_DBG("+");
744         bt_transfer_info_t *transfer_info;
745         int current_progress = 0;
746         int previous_progress;
747         GVariant *param = NULL;
748         int result = BLUETOOTH_ERROR_NONE;
749
750         transfer_info = __bt_find_transfer_by_path(transfer_path);
751         ret_if(transfer_info == NULL);
752
753         current_progress = (int)(((gdouble)transferred /
754                         (gdouble)transfer_info->file_size) * 100);
755
756         previous_progress = (int)(((gdouble)transfer_info->progress /
757                         (gdouble)transfer_info->file_size) * 100);
758
759         if (current_progress == previous_progress) {
760                 BT_DBG("Same Percentage Value: Do not emit Signal");
761                 return;
762         }
763
764         transfer_info->progress = transferred;
765         param = g_variant_new("(isssstiii)", result,
766                                 transfer_info->filename,
767                                 transfer_info->type,
768                                 transfer_info->device_name,
769                                 transfer_info->address,
770                                 transfer_info->file_size,
771                                 transfer_info->transfer_id,
772                                 current_progress,
773                                 agent_info.server_type);
774         _bt_send_event(BT_OPP_SERVER_EVENT,
775                 BLUETOOTH_EVENT_OBEX_SERVER_TRANSFER_PROGRESS,
776                 param);
777         BT_DBG("-");
778 }
779
780 void _bt_obex_transfer_completed(const char *transfer_path, gboolean success)
781 {
782         bt_transfer_info_t *transfer_info;
783         GVariantBuilder *builder = NULL;
784         GVariant *param = NULL;
785         int result;
786         int i = 0;
787         BT_DBG("Transfer [%s] Success [%d] \n", transfer_path, success);
788
789         result = (success == TRUE) ? BLUETOOTH_ERROR_NONE
790                                 : BLUETOOTH_ERROR_CANCEL;
791
792         transfer_info = __bt_find_transfer_by_path(transfer_path);
793
794         if (transfer_info == NULL) {
795                 BT_DBG("Very small files receiving case, did not get Active status from obexd");
796                 if (agent_info.auth_info == NULL ||
797                                 g_strcmp0(transfer_path,
798                                 agent_info.auth_info->transfer_path) != 0) {
799                         BT_ERR("auth_info is NULL, returning");
800                         return;
801                 }
802
803                 transfer_info = g_new0(bt_transfer_info_t, 1);
804
805                 transfer_info->filename = g_strdup(agent_info.auth_info->filename);
806                 transfer_info->file_size = agent_info.auth_info->file_size;
807                 transfer_info->type = g_strdup(TRANSFER_PUT);
808                 transfer_info->path = g_strdup(agent_info.auth_info->transfer_path);
809                 transfer_info->device_name = g_strdup(agent_info.auth_info->device_name);
810                 transfer_info->transfer_id = __bt_get_transfer_id(transfer_path);
811                 transfer_info->file_path = agent_info.auth_info->file_path;
812                 transfer_info->address = g_strdup(agent_info.auth_info->address);
813
814                 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
815                 for (i = 0; i < 5; i++)
816                         g_variant_builder_add(builder, "y", agent_info.auth_info->contact_auth_info[i]);
817
818                 param = g_variant_new("(isssstii(ay))", result,
819                                         transfer_info->device_name,
820                                         transfer_info->filename,
821                                         transfer_info->type,
822                                         transfer_info->address,
823                                         transfer_info->file_size,
824                                         transfer_info->transfer_id,
825                                         agent_info.server_type,
826                                         builder);
827                 _bt_send_event(BT_OPP_SERVER_EVENT,
828                         BLUETOOTH_EVENT_OBEX_SERVER_TRANSFER_STARTED,
829                         param);
830                 g_variant_builder_unref(builder);
831         }
832         param = g_variant_new("(issssstii)", result,
833                                 transfer_info->filename,
834                                 transfer_info->type,
835                                 transfer_info->device_name,
836                                 transfer_info->file_path,
837                                 transfer_info->address,
838                                 transfer_info->file_size,
839                                 transfer_info->transfer_id,
840                                 agent_info.server_type);
841         _bt_send_event(BT_OPP_SERVER_EVENT,
842                 BLUETOOTH_EVENT_OBEX_SERVER_TRANSFER_COMPLETED,
843                 param);
844         transfers = g_slist_remove(transfers, transfer_info);
845         __bt_free_transfer_info(transfer_info);
846 }
847
848 void _bt_obex_transfer_connected(const char *obj_path)
849 {
850         BT_DBG("+");
851
852         int result = BLUETOOTH_ERROR_NONE;
853         GVariant *param = NULL;
854         bt_transfer_info_t *transfer_info = NULL;
855
856         transfer_info = g_new0(bt_transfer_info_t, 1);
857         __bt_get_transfer_properties(transfer_info, obj_path);
858         INFO_SECURE("Address[%s] Name[%s] TransferID[%d] ", transfer_info->address,
859                         transfer_info->device_name, transfer_info->transfer_id);
860
861         param = g_variant_new("(issi)", result, transfer_info->address,
862                         transfer_info->device_name, transfer_info->transfer_id);
863
864         _bt_send_event(BT_OPP_SERVER_EVENT,
865                 BLUETOOTH_EVENT_OBEX_SERVER_TRANSFER_CONNECTED,
866                 param);
867
868         __bt_free_transfer_info(transfer_info);
869         BT_DBG("-");
870 }
871
872 void _bt_obex_transfer_disconnected(char * obj_path)
873 {
874         BT_DBG("+");
875
876         int result = BLUETOOTH_ERROR_NONE;
877         GVariant *param = NULL;
878         bt_session_info_t *session = NULL;
879         int transfer_id = -1;
880
881         session = __bt_find_session_by_path(obj_path);
882         ret_if(session == NULL);
883
884         transfer_id = __bt_get_transfer_id(obj_path);
885         DBG_SECURE("transfer_id: [%d]", transfer_id);
886
887         DBG_SECURE("%s", session->address);
888         param = g_variant_new("(isi)", result, session->address, transfer_id);
889         _bt_send_event(BT_OPP_SERVER_EVENT,
890                 BLUETOOTH_EVENT_OBEX_SERVER_TRANSFER_DISCONNECTED,
891                 param);
892         session_list = g_slist_remove(session_list, session);
893         g_free(session->address);
894         g_free(session->path);
895         g_free(session);
896         BT_DBG("-");
897 }
898
899 int _bt_register_obex_server(void)
900 {
901         GDBusConnection *g_conn;
902         GDBusProxy *manager_proxy;
903         GVariant *result = NULL;
904         GError *g_error = NULL;
905
906         /* Get the session bus. */
907         g_conn = _bt_gdbus_get_system_gconn();
908         retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
909
910         _bt_obex_agent_new(BT_OBEX_SERVER_AGENT_PATH);
911
912         _bt_obex_setup(BT_OBEX_SERVER_AGENT_PATH);
913
914         _bt_obex_set_authorize_cb(BT_OBEX_SERVER_AGENT_PATH,
915                                         __bt_authorize_cb, NULL);
916
917         manager_proxy = g_dbus_proxy_new_sync(g_conn, G_DBUS_PROXY_FLAGS_NONE,
918                                                 NULL, BT_OBEX_SERVICE,
919                                                 BT_OBEX_PATH,
920                                                 BT_OBEX_MANAGER,
921                                                 NULL, &g_error);
922
923         if (manager_proxy == NULL)
924                 return BLUETOOTH_ERROR_INTERNAL;
925
926         result = g_dbus_proxy_call_sync(manager_proxy, "RegisterAgent",
927                                 g_variant_new("(o)", BT_OBEX_SERVER_AGENT_PATH),
928                                 G_DBUS_CALL_FLAGS_NONE,
929                                 DBUS_TIMEOUT, NULL,
930                                 &g_error);
931
932         if (g_error != NULL) {
933                 BT_ERR("Agent registration failed: %s\n", g_error->message);
934                 g_object_unref(manager_proxy);
935                 g_error_free(g_error);
936                 return BLUETOOTH_ERROR_INTERNAL;
937         }
938
939         if (result)
940                 g_variant_unref(result);
941
942         agent_info.proxy = manager_proxy;
943
944         return BLUETOOTH_ERROR_NONE;
945 }
946
947 int _bt_unregister_obex_server(void)
948 {
949         GVariant *result = NULL;
950         GError *g_error = NULL;
951
952         retv_if(agent_info.proxy == NULL,
953                                 BLUETOOTH_ERROR_INTERNAL);
954
955         result = g_dbus_proxy_call_sync(agent_info.proxy, "UnregisterAgent",
956                                 g_variant_new("(o)", BT_OBEX_SERVER_AGENT_PATH),
957                                 G_DBUS_CALL_FLAGS_NONE,
958                                 DBUS_TIMEOUT, NULL,
959                                 &g_error);
960         if (g_error != NULL) {
961                 BT_ERR("Agent unregistration failed: %s", g_error->message);
962                 g_error_free(g_error);
963         }
964
965         if (result)
966                 g_variant_unref(result);
967
968         _bt_obex_agent_destroy(BT_OBEX_SERVER_AGENT_PATH);
969         g_object_unref(agent_info.proxy);
970         agent_info.proxy = NULL;
971
972         return BLUETOOTH_ERROR_NONE;
973 }
974
975 gboolean __bt_check_folder_path(const char *dest_path)
976 {
977         DIR *dp;
978
979         retv_if(dest_path == NULL, FALSE);
980
981         dp = opendir(dest_path);
982
983         if (dp == NULL) {
984                 BT_ERR("The directory does not exist");
985                 return FALSE;
986         }
987
988         closedir(dp);
989
990         return TRUE;
991 }
992
993 char *__bt_transfer_folder_path(char *dest_path)
994 {
995         char *dst_path = (char *)g_malloc0(BT_OBEX_PATH_MAX_LENGTH);
996         if (g_str_has_prefix(dest_path, BT_OBEX_PATH_PREFIX))
997                 snprintf(dst_path, BT_OBEX_PATH_MAX_LENGTH, BT_OBEX_DEFAULT_PATH"%s", dest_path + strlen(BT_OBEX_PATH_PREFIX));
998         else
999                 snprintf(dst_path, BT_OBEX_PATH_MAX_LENGTH, "%s", dest_path);
1000
1001         BT_INFO("obex transfed path : %s", dst_path);
1002         return dst_path;
1003 }
1004
1005 int _bt_obex_server_allocate(char *sender, const char *dest_path, int app_pid, gboolean is_native)
1006 {
1007         BT_DBG("+");
1008
1009         char *dst_path;
1010         dst_path = __bt_transfer_folder_path((char *)dest_path);
1011
1012         if (__bt_check_folder_path(dst_path) == FALSE) {
1013                 g_free(dst_path);
1014                 return BLUETOOTH_ERROR_INVALID_PARAM;
1015         }
1016
1017         if (is_native == TRUE) {
1018                 if (agent_info.native_server) {
1019                         BT_ERR("obex native server busy");
1020                         g_free(dst_path);
1021                         return BLUETOOTH_ERROR_DEVICE_BUSY;
1022                 }
1023
1024                 /* Force to change the control to native */
1025                 agent_info.native_server = g_malloc0(sizeof(bt_server_info_t));
1026                 agent_info.native_server->dest_path = g_strdup(dst_path);
1027                 agent_info.native_server->sender = g_strdup(sender);
1028                 agent_info.native_server->app_pid = app_pid;
1029                 agent_info.server_type = BT_NATIVE_SERVER;
1030                 _bt_unregister_osp_server_in_agent(BT_OBEX_SERVER, NULL);
1031         } else {
1032                 if (agent_info.custom_server) {
1033                         BT_ERR("obex custom server busy");
1034                         g_free(dst_path);
1035                         return BLUETOOTH_ERROR_DEVICE_BUSY;
1036                 }
1037
1038                 /* Force to change the control to custom */
1039                 agent_info.custom_server = g_malloc0(sizeof(bt_server_info_t));
1040                 agent_info.custom_server->dest_path = g_strdup(dst_path);
1041                 agent_info.custom_server->sender = g_strdup(sender);
1042                 agent_info.custom_server->app_pid = app_pid;
1043                 agent_info.server_type = BT_CUSTOM_SERVER;
1044                 _bt_register_osp_server_in_agent(BT_OBEX_SERVER, NULL, NULL, -1);
1045         }
1046
1047         g_free(dst_path);
1048         BT_DBG("-");
1049         return BLUETOOTH_ERROR_NONE;
1050 }
1051
1052 int _bt_obex_server_deallocate(int app_pid, gboolean is_native)
1053 {
1054         if (is_native == TRUE) {
1055                 retv_if(agent_info.native_server == NULL,
1056                                 BLUETOOTH_ERROR_AGENT_DOES_NOT_EXIST);
1057
1058                 retv_if(agent_info.native_server->app_pid != app_pid,
1059                                 BLUETOOTH_ERROR_ACCESS_DENIED);
1060
1061                 __bt_free_server_info(agent_info.native_server);
1062                 agent_info.native_server = NULL;
1063
1064                 /* Change the control to custom */
1065                 if (agent_info.custom_server) {
1066                         agent_info.server_type = BT_CUSTOM_SERVER;
1067                         _bt_register_osp_server_in_agent(BT_OBEX_SERVER,
1068                                                         NULL, NULL, -1);
1069                 }
1070         } else {
1071                 retv_if(agent_info.custom_server == NULL,
1072                                 BLUETOOTH_ERROR_AGENT_DOES_NOT_EXIST);
1073
1074                 retv_if(agent_info.custom_server->app_pid != app_pid,
1075                                 BLUETOOTH_ERROR_ACCESS_DENIED);
1076
1077                 __bt_free_server_info(agent_info.custom_server);
1078                 agent_info.custom_server = NULL;
1079
1080                 _bt_unregister_osp_server_in_agent(BT_OBEX_SERVER, NULL);
1081
1082                 /* Change the control to native */
1083                 if (agent_info.native_server)
1084                         agent_info.server_type = BT_NATIVE_SERVER;
1085         }
1086
1087         return BLUETOOTH_ERROR_NONE;
1088 }
1089
1090 int _bt_obex_server_accept_authorize(const char *filename, gboolean is_native)
1091 {
1092         char file_path[BT_FILE_PATH_MAX] = { 0 };
1093         bt_server_info_t *server_info;
1094
1095         BT_CHECK_PARAMETER(filename, return);
1096
1097         retv_if(agent_info.auth_info == NULL, BLUETOOTH_ERROR_INTERNAL);
1098
1099         retv_if(agent_info.auth_info->reply_context == NULL,
1100                                 BLUETOOTH_ERROR_INTERNAL);
1101
1102         if (is_native == TRUE)
1103                 server_info = agent_info.native_server;
1104         else
1105                 server_info = agent_info.custom_server;
1106
1107         retv_if(server_info == NULL, BLUETOOTH_ERROR_INTERNAL);
1108
1109         if (server_info->dest_path != NULL)
1110                 snprintf(file_path, sizeof(file_path), "%s/%s",
1111                         server_info->dest_path, filename);
1112         else
1113                 snprintf(file_path, sizeof(file_path), "%s", filename);
1114
1115         g_dbus_method_invocation_return_value(agent_info.auth_info->reply_context,
1116                 g_variant_new("(s)", &file_path));
1117         agent_info.auth_info->reply_context = NULL;
1118         agent_info.auth_info->file_path = g_strdup(file_path);
1119         g_free(agent_info.auth_info->filename);
1120         agent_info.auth_info->filename = g_strdup(filename);
1121
1122         return BLUETOOTH_ERROR_NONE;
1123 }
1124
1125 void _bt_obex_server_reply_accept(void)
1126 {
1127         GVariant *param = NULL;
1128         bt_session_info_t *session_info = NULL;
1129         int result = BLUETOOTH_ERROR_NONE;
1130         param = g_variant_new("(istss)", result,
1131                         agent_info.auth_info->filename,
1132                         agent_info.auth_info->file_size,
1133                         agent_info.auth_info->address,
1134                         agent_info.auth_info->device_name);
1135         BT_INFO("Send Obex Authorize");
1136         _bt_send_event(BT_OPP_SERVER_EVENT, BLUETOOTH_EVENT_OBEX_SERVER_TRANSFER_AUTHORIZE, param);
1137
1138         session_info = __bt_find_session_by_path(agent_info.auth_info->transfer_path);
1139
1140         if (NULL == session_info)
1141                 BT_ERR("Couldn't get the session info from the list");
1142         else
1143                 session_info->authorized = TRUE;
1144 }
1145
1146 int _bt_obex_server_reject_authorize(void)
1147 {
1148         GError *g_error;
1149
1150         retv_if(agent_info.auth_info->reply_context == NULL,
1151                                 BLUETOOTH_ERROR_INTERNAL);
1152
1153         g_error = g_error_new(__bt_obex_error_quark(),
1154                         BT_OBEX_AGENT_ERROR_CANCEL,
1155                         "CancelledByUser");
1156
1157         g_dbus_method_invocation_return_gerror(agent_info.auth_info->reply_context,
1158                         g_error);
1159         g_error_free(g_error);
1160
1161         __bt_free_auth_info(agent_info.auth_info);
1162         agent_info.auth_info = NULL;
1163
1164         return BLUETOOTH_ERROR_NONE;
1165 }
1166
1167 int _bt_obex_server_set_destination_path(const char *dest_path,
1168                                                 gboolean is_native)
1169 {
1170         bt_server_info_t *server_info;
1171         BT_CHECK_PARAMETER(dest_path, return);
1172
1173         char *dst_path;
1174         dst_path = __bt_transfer_folder_path((char *)dest_path);
1175
1176         DIR *dp = NULL;
1177
1178         dp = opendir(dst_path);
1179
1180         if (dp == NULL) {
1181                 BT_ERR("The directory does not exist");
1182                 g_free(dst_path);
1183                 return BLUETOOTH_ERROR_INVALID_PARAM;
1184         }
1185
1186         closedir(dp);
1187
1188         if (is_native == TRUE)
1189                 server_info = agent_info.native_server;
1190         else
1191                 server_info = agent_info.custom_server;
1192
1193         if (!server_info) {
1194                 BT_ERR("obex server info is NULL");
1195                 g_free(dst_path);
1196                 return BLUETOOTH_ERROR_AGENT_DOES_NOT_EXIST;
1197         }
1198
1199         g_free(server_info->dest_path);
1200         server_info->dest_path = g_strdup(dst_path);
1201
1202         g_free(dst_path);
1203         return BLUETOOTH_ERROR_NONE;
1204 }
1205
1206 int _bt_obex_server_set_root(const char *root)
1207 {
1208         GVariant *result = NULL;
1209         GError *g_error = NULL;
1210         GVariant *folder = NULL;
1211         char *string = "Root";
1212         DIR *dp = NULL;
1213
1214         BT_CHECK_PARAMETER(root, return);
1215
1216         char *dst_root;
1217         dst_root = __bt_transfer_folder_path((char *)root);
1218
1219         if (!agent_info.proxy) {
1220                 BT_ERR("obex agent_info proxy error");
1221                 g_free(dst_root);
1222                 return BLUETOOTH_ERROR_INTERNAL;
1223         }
1224
1225         dp = opendir(dst_root);
1226
1227         if (dp == NULL) {
1228                 BT_ERR("The directory does not exist");
1229                 g_free(dst_root);
1230                 return BLUETOOTH_ERROR_INVALID_PARAM;
1231         }
1232
1233         closedir(dp);
1234
1235         folder = g_variant_new_string(dst_root);
1236         result = g_dbus_proxy_call_sync(agent_info.proxy, "SetProperty",
1237                         g_variant_new("(sv)", string, folder),
1238                         G_DBUS_CALL_FLAGS_NONE,
1239                         DBUS_TIMEOUT, NULL,
1240                         &g_error);
1241
1242         if (g_error) {
1243                 BT_ERR("SetProperty Fail: %s", g_error->message);
1244                 g_error_free(g_error);
1245                 g_free(dst_root);
1246                 return BLUETOOTH_ERROR_INTERNAL;
1247         }
1248
1249         if (result)
1250                 g_variant_unref(result);
1251
1252         g_free(dst_root);
1253         return BLUETOOTH_ERROR_NONE;
1254 }
1255
1256 int _bt_obex_server_cancel_transfer(int transfer_id)
1257 {
1258         bt_transfer_info_t *transfer = NULL;
1259         GDBusProxy *proxy;
1260         GVariant *result = NULL;
1261         GError *err = NULL;
1262         BT_DBG("+");
1263         transfer = __bt_find_transfer_by_id(transfer_id);
1264
1265         retv_if(transfer == NULL, BLUETOOTH_ERROR_NOT_FOUND);
1266         proxy = __bt_get_transfer_proxy(transfer->path);
1267
1268         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1269
1270         result = g_dbus_proxy_call_sync(proxy, "Cancel", NULL,
1271                 G_DBUS_CALL_FLAGS_NONE,
1272                 DBUS_TIMEOUT, NULL, &err);
1273         if (err) {
1274                 BT_ERR("Dbus Err: %s", err->message);
1275                 g_clear_error(&err);
1276         }
1277
1278         g_object_unref(proxy);
1279
1280         if (result)
1281                 g_variant_unref(result);
1282
1283         return BLUETOOTH_ERROR_NONE;
1284 }
1285
1286 int _bt_obex_server_cancel_all_transfers(void)
1287 {
1288         GSList *l;
1289         bt_transfer_info_t *transfer;
1290
1291         for (l = transfers; l != NULL; l = l->next) {
1292                 transfer = l->data;
1293
1294                 if (transfer == NULL)
1295                         continue;
1296
1297                 _bt_obex_server_cancel_transfer(transfer->transfer_id);
1298         }
1299
1300         return BLUETOOTH_ERROR_NONE;
1301 }
1302
1303 int _bt_obex_server_is_activated(gboolean *activated)
1304 {
1305         BT_CHECK_PARAMETER(activated, return);
1306
1307         if (agent_info.custom_server)
1308                 *activated = TRUE;
1309         else
1310                 *activated = FALSE;
1311
1312         return BLUETOOTH_ERROR_NONE;
1313 }
1314
1315 int _bt_obex_server_check_allocation(gboolean *allocation)
1316 {
1317         BT_CHECK_PARAMETER(allocation, return);
1318
1319         if (agent_info.native_server || agent_info.custom_server)
1320                 *allocation = TRUE;
1321         else
1322                 *allocation = FALSE;
1323
1324         return BLUETOOTH_ERROR_NONE;
1325 }
1326
1327 int _bt_obex_server_check_termination(char *sender)
1328 {
1329         BT_CHECK_PARAMETER(sender, return);
1330
1331         if (agent_info.native_server) {
1332                 if (g_strcmp0(sender, agent_info.native_server->sender) == 0) {
1333                         _bt_obex_server_deallocate(agent_info.native_server->app_pid,
1334                                                 TRUE);
1335                 }
1336         }
1337
1338         if (agent_info.custom_server) {
1339                 if (g_strcmp0(sender, agent_info.custom_server->sender) == 0) {
1340                         _bt_obex_server_deallocate(agent_info.custom_server->app_pid,
1341                                                 FALSE);
1342                 }
1343         }
1344
1345         return BLUETOOTH_ERROR_NONE;
1346 }
1347
1348 int _bt_obex_server_is_receiving(gboolean *receiving)
1349 {
1350         BT_CHECK_PARAMETER(receiving, return);
1351
1352         if (transfers == NULL || g_slist_length(transfers) == 0)
1353                 *receiving = FALSE;
1354         else
1355                 *receiving = TRUE;
1356
1357         return BLUETOOTH_ERROR_NONE;
1358 }
1359
1360 gboolean __bt_obex_server_accept_timeout_cb(gpointer user_data)
1361 {
1362         request_info_t *req_info;
1363         GVariant *out_param1 = NULL;
1364         int result = BLUETOOTH_ERROR_TIMEOUT;
1365
1366         /* Already reply in _bt_obex_transfer_started */
1367         retv_if(agent_info.accept_id == 0, FALSE);
1368
1369         req_info = _bt_get_request_info(agent_info.accept_id);
1370         if (req_info == NULL || req_info->context == NULL) {
1371                 BT_ERR("info is NULL");
1372                 return FALSE;
1373         }
1374
1375         agent_info.accept_id = 0;
1376         GArray *g_out_param1 = NULL;
1377         g_out_param1 = g_array_new(FALSE, FALSE, sizeof(gchar));
1378         if (out_param1 == NULL) {
1379                 out_param1 = g_variant_new_from_data((const GVariantType *)"ay",
1380                                 g_out_param1->data, g_out_param1->len,
1381                                 TRUE, NULL, NULL);
1382         }
1383
1384         g_dbus_method_invocation_return_value(req_info->context,
1385                         g_variant_new("(iv)", result, out_param1));
1386         g_array_free(g_out_param1, TRUE);
1387         _bt_delete_request_list(req_info->req_id);
1388
1389         return FALSE;
1390 }
1391
1392 /* To support the BOT  */
1393 int _bt_obex_server_accept_connection(int request_id)
1394 {
1395         if (!_bt_agent_reply_authorize(TRUE))
1396                 return BLUETOOTH_ERROR_INTERNAL;
1397
1398         agent_info.accept_id = request_id;
1399
1400         g_timeout_add(BT_SERVER_ACCEPT_TIMEOUT,
1401                         (GSourceFunc)__bt_obex_server_accept_timeout_cb,
1402                         NULL);
1403
1404         return BLUETOOTH_ERROR_NONE;
1405 }
1406
1407 /* To support the BOT  */
1408 int _bt_obex_server_reject_connection(void)
1409 {
1410         if (!_bt_agent_reply_authorize(FALSE))
1411                 return BLUETOOTH_ERROR_INTERNAL;
1412
1413         return BLUETOOTH_ERROR_NONE;
1414 }
1415
1416 int _bt_opp_get_server_progress(int transfer_id, guint8 *progress)
1417 {
1418         bt_transfer_info_t *requested_transfer = NULL;
1419         requested_transfer = __bt_find_transfer_by_id(transfer_id);
1420         if (requested_transfer == NULL) {
1421                 BT_ERR("No Matching Inbound transfer");
1422                 return BLUETOOTH_ERROR_NOT_FOUND;
1423         }
1424
1425         *progress = (int)(((double)requested_transfer->progress /
1426                         requested_transfer->file_size) * 100);
1427
1428         BT_DBG("Percentage: %d", *progress);
1429         return BLUETOOTH_ERROR_NONE;
1430 }