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