e534dce5b9af9056c3e1278b7a8bc2242fcab6a0
[platform/core/connectivity/bluetooth-frwk.git] / bt-service / bt-service-obex-server.c
1 /*
2  * bluetooth-frwk
3  *
4  * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *              http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19
20 #include <dbus/dbus-glib.h>
21 #include <dbus/dbus.h>
22 #include <stdio.h>
23 #include <glib.h>
24 #include <dlog.h>
25 #include <string.h>
26 #include <dirent.h>
27 #include <vconf.h>
28
29 #include "bluetooth-api.h"
30 #include "bt-internal-types.h"
31
32 #include "bt-service-common.h"
33 #include "bt-service-event.h"
34 #include "bt-service-util.h"
35 #include "bt-service-obex-agent.h"
36 #include "bt-service-obex-server.h"
37 #include "bt-service-agent.h"
38
39 #define BT_OBEX_SERVER_AGENT_PATH "/org/obex/server_agent"
40 #define BT_OBEX_SERVICE "org.bluez.obex"
41 #define BT_OBEX_MANAGER "org.bluez.obex.AgentManager1"
42 #define BT_OBEX_PATH "/org/bluez/obex"
43
44 typedef struct {
45         char *filename;
46         char *path;
47         char *type;
48         char *device_name;
49         int transfer_id;
50         gint64 file_size;
51 } bt_transfer_info_t;
52
53 typedef struct {
54         DBusGMethodInvocation *reply_context;
55         gint64 file_size;
56         char *filename;
57         char *device_name;
58         char *transfer_path;
59 } bt_auth_info_t;
60
61 typedef struct {
62         char *dest_path;
63         char *sender;
64         int app_pid;
65 } bt_server_info_t;
66
67 typedef struct {
68         BtObexAgent *obex_agent;
69         DBusGProxy *proxy;
70         int server_type;
71         int accept_id;
72         bt_auth_info_t *auth_info;
73         bt_server_info_t *native_server;
74         bt_server_info_t *custom_server;
75 } bt_obex_agent_info_t;
76
77 static GSList *transfers;
78 static bt_obex_agent_info_t agent_info;
79
80 static GQuark __bt_obex_error_quark(void)
81 {
82         static GQuark quark = 0;
83         if (!quark)
84                 quark = g_quark_from_static_string("agent");
85
86         return quark;
87 }
88
89 static bt_transfer_info_t *__bt_find_transfer_by_id(int transfer_id)
90 {
91         GSList *l;
92         bt_transfer_info_t *transfer;
93
94         for (l = transfers; l != NULL; l = l->next) {
95                 transfer = l->data;
96
97                 if (transfer == NULL)
98                         continue;
99
100                 if (transfer->transfer_id == transfer_id)
101                         return transfer;
102         }
103
104         return NULL;
105 }
106
107 static bt_transfer_info_t *__bt_find_transfer_by_path(const char *transfer_path)
108 {
109         GSList *l;
110         bt_transfer_info_t *transfer;
111
112         retv_if(transfer_path == NULL, NULL);
113
114         for (l = transfers; l != NULL; l = l->next) {
115                 transfer = l->data;
116
117                 if (transfer == NULL)
118                         continue;
119
120                 if (g_strcmp0(transfer->path, transfer_path) == 0)
121                         return transfer;
122         }
123
124         return NULL;
125 }
126
127 static void __bt_free_server_info(bt_server_info_t *server_info)
128 {
129         ret_if(server_info == NULL);
130
131         g_free(server_info->sender);
132         g_free(server_info->dest_path);
133         g_free(server_info);
134 }
135
136 static void __bt_free_auth_info(bt_auth_info_t *auto_info)
137 {
138         ret_if(auto_info == NULL);
139
140         g_free(auto_info->filename);
141         g_free(auto_info->transfer_path);
142         g_free(auto_info->device_name);
143         g_free(auto_info);
144 }
145
146 static void __bt_free_transfer_info(bt_transfer_info_t *transfer_info)
147 {
148         ret_if(transfer_info == NULL);
149
150         g_free(transfer_info->path);
151         g_free(transfer_info->filename);
152         g_free(transfer_info->type);
153         g_free(transfer_info->device_name);
154         g_free(transfer_info);
155 }
156
157 static char *__bt_get_remote_device_name(const char *bdaddress)
158 {
159         char *device_path = NULL;
160         char *name = NULL;
161         GHashTable *hash = NULL;
162         GValue *value;
163         DBusGProxy *device_proxy;
164         DBusGProxy *adapter_proxy;
165         DBusGConnection *conn;
166
167         retv_if(bdaddress == NULL, NULL);
168
169         adapter_proxy = _bt_get_adapter_proxy();
170         retv_if(adapter_proxy == NULL, NULL);
171
172         device_path = _bt_get_device_object_path((char *)bdaddress);
173         retv_if(device_path == NULL, NULL);
174
175         conn = _bt_get_system_gconn();
176         retv_if(conn == NULL, NULL);
177
178         device_proxy = dbus_g_proxy_new_for_name(conn, BT_BLUEZ_NAME,
179                                         device_path, BT_PROPERTIES_INTERFACE);
180
181         g_free(device_path);
182         retv_if(device_proxy == NULL, NULL);
183
184         dbus_g_proxy_call(device_proxy, "GetAll", NULL,
185                                 G_TYPE_STRING, BT_DEVICE_INTERFACE,
186                                 G_TYPE_INVALID,
187                                 dbus_g_type_get_map("GHashTable", G_TYPE_STRING,
188                                 G_TYPE_VALUE), &hash, G_TYPE_INVALID);
189
190         g_object_unref(device_proxy);
191
192         if (hash != NULL) {
193                 value = g_hash_table_lookup(hash, "Alias");
194                 name = value ? g_value_dup_string(value) : NULL;
195                 g_hash_table_destroy(hash);
196         }
197
198         return name;
199 }
200
201 static int __bt_get_transfer_id(const char *path)
202 {
203         char *tmp = NULL;
204         if (path == NULL)
205                 return -1;
206
207         tmp = strrchr(path, 'r') + 1;
208         retv_if(tmp == NULL, -1);
209
210         return atoi(tmp);
211 }
212
213 static DBusGProxy *__bt_get_transfer_proxy(const char *transfer_path)
214 {
215         DBusGConnection *conn;
216         DBusGProxy *proxy;
217
218         conn = _bt_get_session_gconn();
219         retv_if(conn == NULL, NULL);
220
221         proxy = dbus_g_proxy_new_for_name(conn,
222                                         BT_OBEX_SERVICE_NAME,
223                                         transfer_path,
224                                         BT_PROPERTIES_INTERFACE);
225
226         return proxy;
227 }
228
229 static int __bt_get_transfer_properties(bt_transfer_info_t *transfer_info,
230                                         const char *transfer_path)
231 {
232         GHashTable *hash = NULL;
233         GValue *value;
234         DBusGProxy *transfer_proxy;
235         char *bdaddress;
236
237         BT_CHECK_PARAMETER(transfer_info, return);
238         BT_CHECK_PARAMETER(transfer_path, return);
239
240         transfer_proxy = __bt_get_transfer_proxy(transfer_path);
241
242         retv_if(transfer_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
243
244
245         dbus_g_proxy_call(transfer_proxy, "GetAll", NULL,
246                                 G_TYPE_STRING, BT_OBEX_TRANSFER_INTERFACE,
247                                 G_TYPE_INVALID,
248                                 dbus_g_type_get_map("GHashTable", G_TYPE_STRING,
249                                 G_TYPE_VALUE), &hash, G_TYPE_INVALID);
250
251         if (hash == NULL) {
252                 g_object_unref(transfer_proxy);
253                 return BLUETOOTH_ERROR_INTERNAL;
254         }
255
256         value = g_hash_table_lookup(hash, "Operation");
257         transfer_info->type = value ? g_strdup(g_value_get_string(value)) : NULL;
258         if (!transfer_info->type)
259                 goto fail;
260
261         value = g_hash_table_lookup(hash, "Name");
262         transfer_info->filename = value ? g_strdup(g_value_get_string(value)) : NULL;
263         if (!transfer_info->filename)
264                 goto fail;
265
266         value = g_hash_table_lookup(hash, "Size");
267         transfer_info->file_size  = value ? g_value_get_uint64(value) : 0;
268
269         transfer_info->path = g_strdup(transfer_path);
270         transfer_info->transfer_id = __bt_get_transfer_id(transfer_path);
271
272         value = g_hash_table_lookup(hash, "Address");
273         bdaddress = value ? (char *)g_value_get_string(value) : NULL;
274         if (!bdaddress)
275                 goto fail;
276
277         transfer_info->device_name = __bt_get_remote_device_name(bdaddress);
278         if (!transfer_info->device_name)
279                 transfer_info->device_name = g_strdup(bdaddress);
280
281         g_hash_table_destroy(hash);
282         g_object_unref(transfer_proxy);
283         return BLUETOOTH_ERROR_NONE;
284
285 fail:
286         g_hash_table_destroy(hash);
287         g_object_unref(transfer_proxy);
288         return BLUETOOTH_ERROR_INTERNAL;
289 }
290
291 static gboolean __bt_authorize_cb(DBusGMethodInvocation *context,
292                                         const char *path,
293                                         gpointer user_data)
294 {
295         char *device_name = NULL;
296         int result = BLUETOOTH_ERROR_NONE;
297         DBusGProxy *transfer_proxy;
298         GHashTable *hash = NULL;
299         GValue *value;
300         char * bdaddress = NULL;
301
302         BT_DBG(" path [%s] \n", path);
303
304         transfer_proxy = __bt_get_transfer_proxy(path);
305
306         retv_if(transfer_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
307
308         dbus_g_proxy_call(transfer_proxy, "GetAll", NULL,
309                                 G_TYPE_STRING, BT_OBEX_TRANSFER_INTERFACE,
310                                 G_TYPE_INVALID,
311                                 dbus_g_type_get_map("GHashTable", G_TYPE_STRING,
312                                 G_TYPE_VALUE), &hash, G_TYPE_INVALID);
313
314         if (hash == NULL) {
315                 g_object_unref(transfer_proxy);
316                 return FALSE;
317         }
318
319         __bt_free_auth_info(agent_info.auth_info);
320
321         agent_info.auth_info = g_malloc(sizeof(bt_auth_info_t));
322
323         agent_info.auth_info->reply_context = context;
324         agent_info.auth_info->transfer_path = g_strdup(path);
325
326         value = g_hash_table_lookup(hash, "Name");
327         agent_info.auth_info->filename = value ? g_strdup(g_value_get_string(value)) : NULL;
328
329         value = g_hash_table_lookup(hash, "Size");
330         agent_info.auth_info->file_size  = value ? g_value_get_uint64(value) : 0;
331
332         value = g_hash_table_lookup(hash, "Address");
333         bdaddress = value ? (char *)g_value_get_string(value) : NULL;
334
335         device_name = __bt_get_remote_device_name(bdaddress);
336
337         if (!device_name)
338                 device_name = g_strdup(bdaddress);
339
340         agent_info.auth_info->device_name = device_name;
341
342         g_hash_table_destroy(hash);
343         g_object_unref(transfer_proxy);
344
345         if (agent_info.server_type == BT_CUSTOM_SERVER) {
346                 /* No need to send the event */
347                 _bt_obex_server_accept_authorize(agent_info.auth_info->filename, FALSE);
348                 return TRUE;
349         }
350
351         _bt_send_event(BT_OPP_SERVER_EVENT,
352                 BLUETOOTH_EVENT_OBEX_SERVER_TRANSFER_AUTHORIZE,
353                 DBUS_TYPE_INT32, &result,
354                 DBUS_TYPE_STRING, &agent_info.auth_info->filename,
355                 DBUS_TYPE_UINT64, &agent_info.auth_info->file_size,
356                 DBUS_TYPE_INVALID);
357
358         return TRUE;
359 }
360
361 void _bt_obex_transfer_started(const char *transfer_path)
362 {
363         bt_transfer_info_t *transfer_info;
364         request_info_t *req_info;
365         GArray *out_param1 = NULL;
366         GArray *out_param2 = NULL;
367         int result = BLUETOOTH_ERROR_NONE;
368
369         BT_DBG("%s", transfer_path);
370
371         transfer_info = g_malloc0(sizeof(bt_transfer_info_t));
372
373         if (agent_info.auth_info != NULL
374              && g_strcmp0(transfer_path, agent_info.auth_info->transfer_path) == 0) {
375                 transfer_info->filename = g_strdup(agent_info.auth_info->filename);
376                 transfer_info->file_size = agent_info.auth_info->file_size;
377                 transfer_info->type = g_strdup(TRANSFER_PUT);
378                 transfer_info->path = g_strdup(agent_info.auth_info->transfer_path);
379                 transfer_info->device_name = g_strdup(agent_info.auth_info->device_name);
380                 transfer_info->transfer_id = __bt_get_transfer_id(transfer_path);
381         } else {
382                 if (__bt_get_transfer_properties(transfer_info, transfer_path) < 0) {
383                         BT_ERR("Get Properties failed");
384                         __bt_free_auth_info(agent_info.auth_info);
385                         __bt_free_transfer_info(transfer_info);
386                         agent_info.auth_info = NULL;
387                         return;
388                 }
389                 agent_info.server_type = BT_FTP_SERVER;
390         }
391
392         __bt_free_auth_info(agent_info.auth_info);
393         agent_info.auth_info = NULL;
394
395         if (agent_info.server_type == BT_CUSTOM_SERVER) {
396                 if (agent_info.custom_server == NULL) {
397                         __bt_free_transfer_info(transfer_info);
398                         return;
399                 }
400
401                 req_info = _bt_get_request_info(agent_info.accept_id);
402                 if (req_info == NULL || req_info->context == NULL) {
403                         BT_ERR("info is NULL");
404                         goto done;
405                 }
406
407                 agent_info.accept_id = 0;
408                 result = BLUETOOTH_ERROR_NONE;
409
410                 out_param1 = g_array_new(FALSE, FALSE, sizeof(gchar));
411                 out_param2 = g_array_new(FALSE, FALSE, sizeof(gchar));
412
413                 g_array_append_vals(out_param2, &result, sizeof(int));
414
415                 dbus_g_method_return(req_info->context, out_param1, out_param2);
416
417                 g_array_free(out_param1, TRUE);
418                 g_array_free(out_param2, TRUE);
419
420                 _bt_delete_request_list(req_info->req_id);
421         }
422 done:
423         transfers = g_slist_append(transfers, transfer_info);
424
425         BT_DBG("Transfer id %d\n", transfer_info->transfer_id);
426
427         _bt_send_event(BT_OPP_SERVER_EVENT,
428                 BLUETOOTH_EVENT_OBEX_SERVER_TRANSFER_STARTED,
429                 DBUS_TYPE_INT32, &result,
430                 DBUS_TYPE_STRING, &transfer_info->filename,
431                 DBUS_TYPE_STRING, &transfer_info->type,
432                 DBUS_TYPE_UINT64, &transfer_info->file_size,
433                 DBUS_TYPE_INT32, &transfer_info->transfer_id,
434                 DBUS_TYPE_INT32, &agent_info.server_type,
435                 DBUS_TYPE_INVALID);
436 }
437
438 void _bt_obex_transfer_progress(const char *transfer_path,
439                                         int transferred)
440 {
441         bt_transfer_info_t *transfer_info;
442         int progress = 0;
443         int result = BLUETOOTH_ERROR_NONE;
444
445         transfer_info = __bt_find_transfer_by_path(transfer_path);
446         ret_if(transfer_info == NULL);
447
448         if (transfer_info->file_size <= 0)
449                 return;
450
451         progress = (int)(((gdouble)transferred /
452                         (gdouble)transfer_info->file_size) * 100);
453
454         _bt_send_event(BT_OPP_SERVER_EVENT,
455                 BLUETOOTH_EVENT_OBEX_SERVER_TRANSFER_PROGRESS,
456                 DBUS_TYPE_INT32, &result,
457                 DBUS_TYPE_STRING, &transfer_info->filename,
458                 DBUS_TYPE_STRING, &transfer_info->type,
459                 DBUS_TYPE_UINT64, &transfer_info->file_size,
460                 DBUS_TYPE_INT32, &transfer_info->transfer_id,
461                 DBUS_TYPE_INT32, &progress,
462                 DBUS_TYPE_INT32, &agent_info.server_type,
463                 DBUS_TYPE_INVALID);
464 }
465
466 void _bt_obex_transfer_completed(const char *transfer_path, gboolean success)
467 {
468         bt_transfer_info_t *transfer_info;
469         int result;
470         BT_DBG("Transfer [%s] Success [%d] \n", transfer_path, success);
471
472         result = (success == TRUE) ? BLUETOOTH_ERROR_NONE
473                                 : BLUETOOTH_ERROR_CANCEL;
474
475         transfer_info = __bt_find_transfer_by_path(transfer_path);
476         ret_if(transfer_info == NULL);
477
478         _bt_send_event(BT_OPP_SERVER_EVENT,
479                 BLUETOOTH_EVENT_OBEX_SERVER_TRANSFER_COMPLETED,
480                 DBUS_TYPE_INT32, &result,
481                 DBUS_TYPE_STRING, &transfer_info->filename,
482                 DBUS_TYPE_STRING, &transfer_info->type,
483                 DBUS_TYPE_STRING, &transfer_info->device_name,
484                 DBUS_TYPE_UINT64, &transfer_info->file_size,
485                 DBUS_TYPE_INT32, &transfer_info->transfer_id,
486                 DBUS_TYPE_INT32, &agent_info.server_type,
487                 DBUS_TYPE_INVALID);
488
489         transfers = g_slist_remove(transfers, transfer_info);
490         __bt_free_transfer_info(transfer_info);
491 }
492
493 int _bt_register_obex_server(void)
494 {
495         DBusGConnection *g_conn;
496         DBusGProxy *manager_proxy;
497         GError *g_error = NULL;
498
499         /* Get the session bus. */
500         g_conn = _bt_get_session_gconn();
501         retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
502
503         if (!agent_info.obex_agent) {
504                 agent_info.obex_agent = _bt_obex_agent_new();
505
506                 retv_if(agent_info.obex_agent == NULL, BLUETOOTH_ERROR_INTERNAL);
507
508                 _bt_obex_setup(agent_info.obex_agent, BT_OBEX_SERVER_AGENT_PATH);
509
510                 _bt_obex_set_authorize_cb(agent_info.obex_agent,
511                                         __bt_authorize_cb, NULL);
512         }
513
514         manager_proxy = dbus_g_proxy_new_for_name(g_conn, BT_OBEX_SERVICE,
515                                                 BT_OBEX_PATH, BT_OBEX_MANAGER);
516
517         if (manager_proxy == NULL) {
518                 g_object_unref(agent_info.obex_agent);
519                 agent_info.obex_agent = NULL;
520                 return BLUETOOTH_ERROR_INTERNAL;
521         }
522
523         dbus_g_proxy_call(manager_proxy, "RegisterAgent", &g_error,
524                           DBUS_TYPE_G_OBJECT_PATH, BT_OBEX_SERVER_AGENT_PATH,
525                           G_TYPE_INVALID, G_TYPE_INVALID);
526         if (g_error != NULL) {
527                 BT_ERR("Agent registration failed: %s\n", g_error->message);
528                 g_object_unref(agent_info.obex_agent);
529                 agent_info.obex_agent = NULL;
530                 g_object_unref(manager_proxy);
531                 g_error_free(g_error);
532                 return BLUETOOTH_ERROR_INTERNAL;
533         }
534
535         agent_info.proxy = manager_proxy;
536
537         return BLUETOOTH_ERROR_NONE;
538 }
539
540 int _bt_unregister_obex_server(void)
541 {
542         GError *g_error = NULL;
543
544         retv_if(agent_info.obex_agent == NULL,
545                                 BLUETOOTH_ERROR_AGENT_DOES_NOT_EXIST);
546
547         retv_if(agent_info.proxy == NULL,
548                                 BLUETOOTH_ERROR_INTERNAL);
549
550         dbus_g_proxy_call(agent_info.proxy, "UnregisterAgent", &g_error,
551                           DBUS_TYPE_G_OBJECT_PATH, BT_OBEX_SERVER_AGENT_PATH,
552                           G_TYPE_INVALID, G_TYPE_INVALID);
553         if (g_error != NULL) {
554                 BT_ERR("Agent unregistration failed: %s", g_error->message);
555                 g_error_free(g_error);
556         }
557
558         g_object_unref(agent_info.proxy);
559         agent_info.proxy = NULL;
560
561         g_object_unref(agent_info.obex_agent);
562         agent_info.obex_agent = NULL;
563
564         return BLUETOOTH_ERROR_NONE;
565 }
566
567 gboolean __bt_check_folder_path(const char *dest_path)
568 {
569         DIR *dp;
570
571         retv_if(dest_path == NULL, TRUE);
572
573         dp = opendir(dest_path);
574
575         if (dp == NULL) {
576                 BT_ERR("The directory does not exist");
577                 return FALSE;
578         }
579
580         closedir(dp);
581
582         return TRUE;
583 }
584
585 int _bt_obex_server_allocate(char *sender, const char *dest_path, int app_pid, gboolean is_native)
586 {
587         if (__bt_check_folder_path(dest_path) == FALSE)
588                 return BLUETOOTH_ERROR_INVALID_PARAM;
589
590         if (is_native == TRUE) {
591                 retv_if(agent_info.native_server,
592                                 BLUETOOTH_ERROR_DEVICE_BUSY);
593
594                 /* Force to change the control to native */
595                 agent_info.native_server = g_malloc0(sizeof(bt_server_info_t));
596                 agent_info.native_server->dest_path = g_strdup(dest_path);
597                 agent_info.native_server->sender = g_strdup(sender);
598                 agent_info.native_server->app_pid = app_pid;
599                 agent_info.server_type = BT_NATIVE_SERVER;
600                 _bt_unregister_osp_server_in_agent(BT_OBEX_SERVER, NULL);
601         } else {
602                 retv_if(agent_info.custom_server,
603                                 BLUETOOTH_ERROR_DEVICE_BUSY);
604
605                 /* Force to change the control to custom */
606                 agent_info.custom_server = g_malloc0(sizeof(bt_server_info_t));
607                 agent_info.custom_server->dest_path = g_strdup(dest_path);
608                 agent_info.custom_server->sender = g_strdup(sender);
609                 agent_info.custom_server->app_pid = app_pid;
610                 agent_info.server_type = BT_CUSTOM_SERVER;
611                 _bt_register_osp_server_in_agent(BT_OBEX_SERVER, NULL);
612         }
613
614         return BLUETOOTH_ERROR_NONE;
615 }
616
617 int _bt_obex_server_deallocate(int app_pid, gboolean is_native)
618 {
619         if (is_native == TRUE) {
620                 retv_if(agent_info.native_server == NULL,
621                                 BLUETOOTH_ERROR_AGENT_DOES_NOT_EXIST);
622
623                 retv_if(agent_info.native_server->app_pid != app_pid,
624                                 BLUETOOTH_ERROR_ACCESS_DENIED);
625
626                 __bt_free_server_info(agent_info.native_server);
627                 agent_info.native_server = NULL;
628
629                 /* Change the control to custom */
630                 if (agent_info.custom_server) {
631                         agent_info.server_type = BT_CUSTOM_SERVER;
632                         _bt_register_osp_server_in_agent(BT_OBEX_SERVER,
633                                                         NULL);
634                 }
635         } else {
636                 retv_if(agent_info.custom_server == NULL,
637                                 BLUETOOTH_ERROR_AGENT_DOES_NOT_EXIST);
638
639                 retv_if(agent_info.custom_server->app_pid != app_pid,
640                                 BLUETOOTH_ERROR_ACCESS_DENIED);
641
642                 __bt_free_server_info(agent_info.custom_server);
643                 agent_info.custom_server = NULL;
644
645                 _bt_unregister_osp_server_in_agent(BT_OBEX_SERVER, NULL);
646
647                 /* Change the control to native */
648                 if (agent_info.native_server)
649                         agent_info.server_type = BT_NATIVE_SERVER;
650         }
651
652         return BLUETOOTH_ERROR_NONE;
653 }
654
655 int _bt_obex_server_accept_authorize(const char *filename, gboolean is_native)
656 {
657         char file_path[BT_FILE_PATH_MAX] = { 0 };
658         bt_server_info_t *server_info;
659
660         BT_CHECK_PARAMETER(filename, return);
661
662         retv_if(agent_info.auth_info == NULL, BLUETOOTH_ERROR_INTERNAL);
663
664         retv_if(agent_info.auth_info->reply_context == NULL,
665                                 BLUETOOTH_ERROR_INTERNAL);
666
667         if (is_native == TRUE)
668                 server_info = agent_info.native_server;
669         else
670                 server_info = agent_info.custom_server;
671
672         retv_if(server_info == NULL, BLUETOOTH_ERROR_INTERNAL);
673
674         if (server_info->dest_path != NULL)
675                 snprintf(file_path, sizeof(file_path), "%s/%s",
676                         server_info->dest_path, filename);
677         else
678                 snprintf(file_path, sizeof(file_path), "%s", filename);
679
680         dbus_g_method_return(agent_info.auth_info->reply_context,
681                                 file_path);
682
683         agent_info.auth_info->reply_context = NULL;
684
685         return BLUETOOTH_ERROR_NONE;
686 }
687
688 int _bt_obex_server_reject_authorize(void)
689 {
690         GError *g_error;
691
692         retv_if(agent_info.auth_info->reply_context == NULL,
693                                 BLUETOOTH_ERROR_INTERNAL);
694
695         g_error = g_error_new(__bt_obex_error_quark(),
696                         BT_OBEX_AGENT_ERROR_CANCEL,
697                         "CancelledByUser");
698
699         dbus_g_method_return_error(agent_info.auth_info->reply_context,
700                                 g_error);
701         g_error_free(g_error);
702
703         __bt_free_auth_info(agent_info.auth_info);
704         agent_info.auth_info = NULL;
705
706         return BLUETOOTH_ERROR_NONE;
707 }
708
709 int _bt_obex_server_set_destination_path(const char *dest_path,
710                                                 gboolean is_native)
711 {
712         DIR *dp = NULL;
713         bt_server_info_t *server_info;
714
715         BT_CHECK_PARAMETER(dest_path, return);
716
717         dp = opendir(dest_path);
718
719         if (dp == NULL) {
720                 BT_ERR("The directory does not exist");
721                 return BLUETOOTH_ERROR_INVALID_PARAM;
722         }
723
724         closedir(dp);
725
726         if (is_native == TRUE)
727                 server_info = agent_info.native_server;
728         else
729                 server_info = agent_info.custom_server;
730
731         retv_if(server_info == NULL,
732                         BLUETOOTH_ERROR_AGENT_DOES_NOT_EXIST);
733
734         g_free(server_info->dest_path);
735         server_info->dest_path = g_strdup(dest_path);
736
737         return BLUETOOTH_ERROR_NONE;
738 }
739
740 int _bt_obex_server_set_root(const char *root)
741 {
742         GError *g_error = NULL;
743         GValue folder = { 0 };
744         DIR *dp = NULL;
745
746         BT_CHECK_PARAMETER(root, return);
747
748         retv_if(agent_info.proxy == NULL,
749                                 BLUETOOTH_ERROR_INTERNAL);
750
751         dp = opendir(root);
752
753         if (dp == NULL) {
754                 BT_ERR("The directory does not exist");
755                 return BLUETOOTH_ERROR_INVALID_PARAM;
756         }
757
758         closedir(dp);
759
760         g_value_init(&folder, G_TYPE_STRING);
761         g_value_set_string(&folder, root);
762
763         dbus_g_proxy_call(agent_info.proxy, "SetProperty",
764                         &g_error, G_TYPE_STRING, "Root",
765                         G_TYPE_VALUE, &folder, G_TYPE_INVALID, G_TYPE_INVALID);
766
767         g_value_unset(&folder);
768
769         if (g_error) {
770                 BT_ERR("SetProperty Fail: %s", g_error->message);
771                 g_error_free(g_error);
772                 return BLUETOOTH_ERROR_INTERNAL;
773         }
774
775         return BLUETOOTH_ERROR_NONE;
776 }
777
778 int _bt_obex_server_cancel_transfer(int transfer_id)
779 {
780         bt_transfer_info_t *transfer = NULL;
781         DBusGProxy *proxy;
782
783         transfer = __bt_find_transfer_by_id(transfer_id);
784         retv_if(transfer == NULL, BLUETOOTH_ERROR_NOT_FOUND);
785
786         proxy = __bt_get_transfer_proxy(transfer->path);
787
788         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
789
790         dbus_g_proxy_call_no_reply(proxy, "Cancel",
791                                 G_TYPE_INVALID, G_TYPE_INVALID);
792
793         g_object_unref(proxy);
794
795         return BLUETOOTH_ERROR_NONE;
796 }
797
798 int _bt_obex_server_cancel_all_transfers(void)
799 {
800         GSList *l;
801         bt_transfer_info_t *transfer;
802
803         for (l = transfers; l != NULL; l = l->next) {
804                 transfer = l->data;
805
806                 if (transfer == NULL)
807                         continue;
808
809                 _bt_obex_server_cancel_transfer(transfer->transfer_id);
810         }
811
812         return BLUETOOTH_ERROR_NONE;
813 }
814
815 int _bt_obex_server_is_activated(gboolean *activated)
816 {
817         BT_CHECK_PARAMETER(activated, return);
818
819         if (agent_info.custom_server) {
820                 *activated = TRUE;
821         } else {
822                 *activated = FALSE;
823         }
824
825         return BLUETOOTH_ERROR_NONE;
826 }
827
828 int _bt_obex_server_check_allocation(gboolean *allocation)
829 {
830         BT_CHECK_PARAMETER(allocation, return);
831
832         if (agent_info.native_server || agent_info.custom_server) {
833                 *allocation = TRUE;
834         } else {
835                 *allocation = FALSE;
836         }
837
838         return BLUETOOTH_ERROR_NONE;
839 }
840
841 int _bt_obex_server_check_termination(char *sender)
842 {
843         BT_CHECK_PARAMETER(sender, return);
844
845         if (agent_info.native_server) {
846                 if (g_strcmp0(sender, agent_info.native_server->sender) == 0) {
847                         _bt_obex_server_deallocate(agent_info.native_server->app_pid,
848                                                 TRUE);
849                 }
850         }
851
852         if (agent_info.custom_server) {
853                 if (g_strcmp0(sender, agent_info.custom_server->sender) == 0) {
854                         _bt_obex_server_deallocate(agent_info.custom_server->app_pid,
855                                                 FALSE);
856                 }
857         }
858
859         return BLUETOOTH_ERROR_NONE;
860 }
861
862 int _bt_obex_server_is_receiving(gboolean *receiving)
863 {
864         BT_CHECK_PARAMETER(receiving, return);
865
866         if (transfers == NULL || g_slist_length(transfers) == 0) {
867                 *receiving = FALSE;
868         } else {
869                 *receiving = TRUE;
870         }
871
872         return BLUETOOTH_ERROR_NONE;
873 }
874
875 gboolean __bt_obex_server_accept_timeout_cb(gpointer user_data)
876 {
877         request_info_t *req_info;
878         GArray *out_param1;
879         GArray *out_param2;
880         int result = BLUETOOTH_ERROR_TIMEOUT;
881
882         /* Already reply in _bt_obex_transfer_started */
883         retv_if(agent_info.accept_id == 0, FALSE);
884
885         req_info = _bt_get_request_info(agent_info.accept_id);
886         if (req_info == NULL || req_info->context == NULL) {
887                 BT_ERR("info is NULL");
888                 return FALSE;
889         }
890
891         agent_info.accept_id = 0;
892
893         out_param1 = g_array_new(FALSE, FALSE, sizeof(gchar));
894         out_param2 = g_array_new(FALSE, FALSE, sizeof(gchar));
895
896         g_array_append_vals(out_param2, &result, sizeof(int));
897
898         dbus_g_method_return(req_info->context, out_param1, out_param2);
899
900         g_array_free(out_param1, TRUE);
901         g_array_free(out_param2, TRUE);
902
903         _bt_delete_request_list(req_info->req_id);
904
905         return FALSE;
906 }
907
908 /* To support the BOT  */
909 int _bt_obex_server_accept_connection(int request_id)
910 {
911         if (!_bt_agent_reply_authorize(TRUE))
912                 return BLUETOOTH_ERROR_INTERNAL;
913
914         agent_info.accept_id = request_id;
915
916         g_timeout_add(BT_SERVER_ACCEPT_TIMEOUT,
917                         (GSourceFunc)__bt_obex_server_accept_timeout_cb,
918                         NULL);
919
920         return BLUETOOTH_ERROR_NONE;
921 }
922
923 /* To support the BOT  */
924 int _bt_obex_server_reject_connection(void)
925 {
926         if (!_bt_agent_reply_authorize(FALSE))
927                 return BLUETOOTH_ERROR_INTERNAL;
928
929         return BLUETOOTH_ERROR_NONE;
930 }
931