Fix the coding style errors (bt-service)
[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_DPM_ENABLE
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
49 typedef struct {
50         char *filename;
51         char *file_path;
52         char *path;
53         char *type;
54         char *device_name;
55         int transfer_id;
56         gint64 file_size;
57         char *address;
58 } bt_transfer_info_t;
59
60 typedef struct {
61         GDBusMethodInvocation *reply_context;
62         guint64 file_size;
63         char *filename;
64         char *file_path;
65         char *device_name;
66         char *transfer_path;
67         char *address;
68 } bt_auth_info_t;
69
70 typedef struct {
71         char *dest_path;
72         char *sender;
73         int app_pid;
74 } bt_server_info_t;
75
76 typedef struct {
77         GDBusProxy *proxy;
78         int server_type;
79         int accept_id;
80         bt_auth_info_t *auth_info;
81         bt_server_info_t *native_server;
82         bt_server_info_t *custom_server;
83 } bt_obex_agent_info_t;
84
85 static GSList *transfers;
86 static bt_obex_agent_info_t agent_info;
87
88 int _bt_obex_get_native_pid(void)
89 {
90         return agent_info.native_server->app_pid;
91 }
92
93 static GQuark __bt_obex_error_quark(void)
94 {
95         static GQuark quark = 0;
96         if (!quark)
97                 quark = g_quark_from_static_string("agent");
98
99         return quark;
100 }
101
102 static bt_transfer_info_t *__bt_find_transfer_by_id(int transfer_id)
103 {
104         GSList *l;
105         bt_transfer_info_t *transfer;
106
107         for (l = transfers; l != NULL; l = l->next) {
108                 transfer = l->data;
109
110                 if (transfer == NULL)
111                         continue;
112
113                 if (transfer->transfer_id == transfer_id)
114                         return transfer;
115         }
116
117         return NULL;
118 }
119
120 bt_transfer_info_t *__bt_find_transfer_by_address(const char *address)
121 {
122         BT_DBG("+");
123         GSList *l;
124         bt_transfer_info_t *transfer;
125
126         retv_if(address == NULL, NULL);
127
128         for (l = transfers; l != NULL; l = l->next) {
129                 transfer = l->data;
130
131                 if (transfer == NULL)
132                         continue;
133
134                 if (g_strcmp0(transfer->address, address) == 0)
135                         return transfer;
136         }
137         BT_DBG("-");
138         return NULL;
139 }
140
141 static bt_transfer_info_t *__bt_find_transfer_by_path(const char *transfer_path)
142 {
143         GSList *l;
144         bt_transfer_info_t *transfer;
145
146         retv_if(transfer_path == NULL, NULL);
147
148         for (l = transfers; l != NULL; l = l->next) {
149                 transfer = l->data;
150
151                 if (transfer == NULL)
152                         continue;
153
154                 if (g_strcmp0(transfer->path, transfer_path) == 0)
155                         return transfer;
156         }
157
158         return NULL;
159 }
160
161 static void __bt_free_server_info(bt_server_info_t *server_info)
162 {
163         ret_if(server_info == NULL);
164
165         g_free(server_info->sender);
166         g_free(server_info->dest_path);
167         g_free(server_info);
168 }
169
170 static void __bt_free_auth_info(bt_auth_info_t *auto_info)
171 {
172         ret_if(auto_info == NULL);
173
174         g_free(auto_info->filename);
175         g_free(auto_info->transfer_path);
176         g_free(auto_info->device_name);
177         g_free(auto_info->address);
178         g_free(auto_info);
179 }
180
181 static void __bt_free_transfer_info(bt_transfer_info_t *transfer_info)
182 {
183         ret_if(transfer_info == NULL);
184
185         g_free(transfer_info->path);
186         g_free(transfer_info->filename);
187         g_free(transfer_info->file_path);
188         g_free(transfer_info->type);
189         g_free(transfer_info->device_name);
190         g_free(transfer_info->address);
191         g_free(transfer_info);
192 }
193
194 void _bt_obex_check_pending_transfer(const char *address)
195 {
196         BT_DBG("+");
197         GVariant *param = NULL;
198         bt_transfer_info_t *transfer_info = __bt_find_transfer_by_address(address);
199         if (transfer_info != NULL) {
200                 int result = BLUETOOTH_ERROR_CANCEL;
201                 param = g_variant_new("(isssstii)", result,
202                                         transfer_info->filename,
203                                         transfer_info->type,
204                                         transfer_info->device_name,
205                                         transfer_info->file_path,
206                                         transfer_info->file_size,
207                                         transfer_info->transfer_id,
208                                         agent_info.server_type);
209                 _bt_send_event(BT_OPP_SERVER_EVENT,
210                         BLUETOOTH_EVENT_OBEX_SERVER_TRANSFER_COMPLETED,
211                         param);
212                 transfers = g_slist_remove(transfers, transfer_info);
213                 __bt_free_transfer_info(transfer_info);
214         }
215         BT_DBG("-");
216 }
217
218 static char *__bt_get_remote_device_name(const char *bdaddress)
219 {
220         char *device_path = NULL;
221         char *name = NULL;
222         GVariant *value;
223         GVariant *result = NULL;
224         GError *err = NULL;
225         GDBusProxy *device_proxy;
226         GDBusConnection *conn;
227
228         retv_if(bdaddress == NULL, NULL);
229
230         device_path = _bt_get_device_object_path((char *)bdaddress);
231         retv_if(device_path == NULL, NULL);
232
233         conn = _bt_get_system_gconn();
234         retv_if(conn == NULL, NULL);
235         BT_INFO("Device_path %s", device_path);
236         device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
237                                                 NULL, BT_BLUEZ_NAME,
238                                                 device_path,
239                                                 BT_PROPERTIES_INTERFACE,
240                                                 NULL, &err);
241
242         g_free(device_path);
243         retv_if(device_proxy == NULL, NULL);
244
245         result = g_dbus_proxy_call_sync(device_proxy, "GetAll",
246                         g_variant_new("(s)", BT_DEVICE_INTERFACE),
247                         G_DBUS_CALL_FLAGS_NONE,
248                         DBUS_TIMEOUT, NULL,
249                         &err);
250         if (err) {
251                 BT_ERR("DBus Error : %s", err->message);
252                 g_clear_error(&err);
253                 return NULL;
254         }
255         if (result == NULL) {
256                 BT_ERR("g_dbus_proxy_call_sync function return NULL");
257                 return NULL;
258         }
259         g_variant_get(result, "(@a{sv})", &value);
260         g_variant_unref(result);
261
262         g_object_unref(device_proxy);
263         if (value) {
264                 GVariant *temp_value = g_variant_lookup_value(value, "Alias",
265                         G_VARIANT_TYPE_STRING);
266                 g_variant_get(temp_value, "(s)", &name);
267                 if (temp_value)
268                         g_variant_unref(temp_value);
269                 BT_INFO("Alias Name: %s", name);
270         }
271
272         return name;
273 }
274
275 static int __bt_get_transfer_id(const char *path)
276 {
277         char *tmp = NULL;
278         if (path == NULL)
279                 return -1;
280
281         tmp = strrchr(path, 'r') + 1;
282         retv_if(tmp == NULL, -1);
283
284         return atoi(tmp);
285 }
286
287 static GDBusProxy *__bt_get_transfer_proxy(const char *transfer_path)
288 {
289         GDBusConnection *conn;
290         GDBusProxy *proxy;
291         GError *err = NULL;
292
293         conn = _bt_get_session_gconn();
294         retv_if(conn == NULL, NULL);
295
296         proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
297                                         NULL, BT_OBEX_SERVICE_NAME,
298                                         transfer_path,
299                                         BT_OBEX_TRANSFER_INTERFACE,
300                                         NULL, &err);
301
302         if (err) {
303                 BT_ERR("Error : %s", err->message);
304                 g_clear_error(&err);
305                 return NULL;
306         }
307
308         return proxy;
309 }
310
311 static GDBusProxy *__bt_get_transfer_properties_proxy(const char *transfer_path)
312 {
313         GDBusConnection *conn;
314         GDBusProxy *proxy;
315         GError *err = NULL;
316         conn = _bt_get_session_gconn();
317         retv_if(conn == NULL, NULL);
318
319         proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
320                                         NULL,BT_OBEX_SERVICE_NAME,
321                                         transfer_path,
322                                         BT_PROPERTIES_INTERFACE,
323                                         NULL, &err);
324         if (err) {
325                 BT_ERR("Error : %s", err->message);
326                 g_clear_error(&err);
327                 return NULL;
328         }
329         return proxy;
330 }
331
332 static int __bt_get_transfer_properties(bt_transfer_info_t *transfer_info,
333                                         const char *transfer_path)
334 {
335         GDBusProxy *transfer_proxy;
336         char *bdaddress = NULL;
337         GVariant *result = NULL;
338         GError *err = NULL;
339         GVariantIter *iter = NULL;
340         BT_CHECK_PARAMETER(transfer_info, return);
341         BT_CHECK_PARAMETER(transfer_path, return);
342
343         transfer_proxy = __bt_get_transfer_properties_proxy(transfer_path);
344
345         retv_if(transfer_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
346
347         result = g_dbus_proxy_call_sync(transfer_proxy, "GetAll",
348                         g_variant_new("(s)", BT_OBEX_TRANSFER_INTERFACE),
349                         G_DBUS_CALL_FLAGS_NONE,
350                         DBUS_TIMEOUT, NULL,
351                         &err);
352
353         if (err) {
354                 BT_ERR("DBus Error : %s", err->message);
355                 g_clear_error(&err);
356                 goto fail;
357         }
358         if (result == NULL) {
359                 BT_ERR("g_dbus_proxy_call_sync function return NULL");
360                 goto fail;
361         }
362
363         g_variant_get(result, "(a{sv})", &iter);
364         g_variant_unref(result);
365         if (iter) {
366                 const gchar *key;
367                 GVariant *val;
368                 gsize len = 0;
369                 while (g_variant_iter_loop(iter, "{sv}", &key, &val)) {
370                         if (g_strcmp0(key, "Operation") == 0) {
371                                 transfer_info->type = g_variant_dup_string(val, &len);
372                         } else if (g_strcmp0(key, "Name") == 0) {
373                                 transfer_info->filename = g_variant_dup_string(val, &len);
374                         } else if (g_strcmp0(key, "Size") == 0) {
375                                 transfer_info->file_size = g_variant_get_uint64(val);
376                         } else if (g_strcmp0(key, "Address") == 0) {
377                                 transfer_info->address = g_variant_dup_string(val, &len);
378                                 BT_INFO("addressss %s", transfer_info->address);
379                         } else if (g_strcmp0(key, "Filename") == 0) {
380                                 transfer_info->file_path = g_variant_dup_string(val, &len);
381                                 if (!transfer_info->file_path)
382                                         transfer_info->file_path = g_strdup(transfer_info->filename);
383                         }
384                 }
385                 g_variant_iter_free(iter);
386                 if (transfer_info->type == NULL)
387                         goto fail;
388                 if (transfer_info->address == NULL)
389                         goto fail;
390
391                 transfer_info->device_name = __bt_get_remote_device_name(transfer_info->address);
392
393                 if (!transfer_info->device_name)
394                         transfer_info->device_name = g_strdup(bdaddress);
395                 transfer_info->path = g_strdup(transfer_path);
396                 transfer_info->transfer_id = __bt_get_transfer_id(transfer_path);
397         }
398
399         g_object_unref(transfer_proxy);
400         return BLUETOOTH_ERROR_NONE;
401
402 fail:
403         g_object_unref(transfer_proxy);
404         return BLUETOOTH_ERROR_INTERNAL;
405 }
406
407 static gboolean __bt_authorize_cb(GDBusMethodInvocation *context,
408                                         const char *path,
409                                         gpointer user_data)
410 {
411         char *device_name = NULL;
412         int result = BLUETOOTH_ERROR_NONE;
413         GDBusProxy *transfer_properties_proxy;
414         char *bdaddress = NULL;
415         GVariant *ret;
416         GVariantIter *iter;
417         GVariant *param = NULL;
418         GError *err = NULL;
419
420         BT_DBG(" path [%s] \n", path);
421
422         transfer_properties_proxy = __bt_get_transfer_properties_proxy(path);
423
424         retv_if(transfer_properties_proxy == NULL, FALSE);
425
426         ret = g_dbus_proxy_call_sync(transfer_properties_proxy, "GetAll",
427                         g_variant_new("(s)", BT_OBEX_TRANSFER_INTERFACE),
428                         G_DBUS_CALL_FLAGS_NONE,
429                         DBUS_TIMEOUT, NULL,
430                         &err);
431         if (err) {
432                 BT_ERR("DBus Error : %s", err->message);
433                 g_clear_error(&err);
434                 return FALSE;
435         }
436         if (ret == NULL) {
437                 BT_ERR("g_dbus_proxy_call_sync function return NULL");
438                 return FALSE;
439         }
440         g_variant_get(ret, "(a{sv})", &iter);
441         g_variant_unref(ret);
442         if (iter == NULL) {
443                 g_object_unref(transfer_properties_proxy);
444                 return FALSE;
445         }
446
447         __bt_free_auth_info(agent_info.auth_info);
448
449         agent_info.auth_info = g_malloc(sizeof(bt_auth_info_t));
450
451         memset(agent_info.auth_info, 0, sizeof(bt_auth_info_t));
452
453         agent_info.auth_info->reply_context = context;
454
455         agent_info.auth_info->transfer_path = g_strdup(path);
456
457 #ifdef TIZEN_DPM_ENABLE
458         if(_bt_dpm_get_allow_bluetooth_mode() == DPM_BT_HANDSFREE_ONLY) {
459                 /* Free auth info in next function */
460                 _bt_obex_server_reject_authorize();
461                 return FALSE;
462         }
463 #endif
464
465         if (iter) {
466                 const gchar *key;
467                 GVariant *val;
468                 gsize len = 0;
469                 while (g_variant_iter_loop(iter, "{sv}", &key, &val)) {
470                         if (g_strcmp0(key, "Name") == 0) {
471                                 agent_info.auth_info->filename = g_variant_dup_string(val,&len);
472                         } else if (g_strcmp0(key, "Address") == 0) {
473                                 bdaddress = g_variant_dup_string(val, &len);
474                         } else if (g_strcmp0(key, "Size") == 0) {
475                                 agent_info.auth_info->file_size = g_variant_get_uint64(val);
476                         }
477                 }
478                 g_variant_iter_free(iter);
479         }
480
481         device_name = __bt_get_remote_device_name(bdaddress);
482
483         if (!device_name)
484                 device_name = g_strdup(bdaddress);
485
486         agent_info.auth_info->device_name = device_name;
487
488         g_object_unref(transfer_properties_proxy);
489
490         if (agent_info.server_type == BT_CUSTOM_SERVER) {
491                 /* No need to send the event */
492                 _bt_obex_server_accept_authorize(agent_info.auth_info->filename, FALSE);
493                 return TRUE;
494         }
495         param = g_variant_new("(ist)", result,
496                                 agent_info.auth_info->filename,
497                                 agent_info.auth_info->file_size);
498         _bt_send_event(BT_OPP_SERVER_EVENT,
499                 BLUETOOTH_EVENT_OBEX_SERVER_TRANSFER_AUTHORIZE,
500                 param);
501
502         return TRUE;
503 }
504
505 void _bt_obex_transfer_started(const char *transfer_path)
506 {
507         bt_transfer_info_t *transfer_info;
508         request_info_t *req_info;
509         GVariant *out_param1 = NULL;
510         GVariant *param = NULL;
511         int result = BLUETOOTH_ERROR_NONE;
512
513         BT_DBG("%s", transfer_path);
514
515         transfer_info = g_malloc0(sizeof(bt_transfer_info_t));
516
517         if (agent_info.auth_info != NULL
518              && g_strcmp0(transfer_path, agent_info.auth_info->transfer_path) == 0) {
519                 transfer_info->filename = g_strdup(agent_info.auth_info->filename);
520                 transfer_info->file_size = agent_info.auth_info->file_size;
521                 transfer_info->type = g_strdup(TRANSFER_PUT);
522                 transfer_info->path = g_strdup(agent_info.auth_info->transfer_path);
523                 transfer_info->device_name = g_strdup(agent_info.auth_info->device_name);
524                 transfer_info->transfer_id = __bt_get_transfer_id(transfer_path);
525                 transfer_info->file_path = agent_info.auth_info->file_path;
526                 transfer_info->address = g_strdup(agent_info.auth_info->address);
527         } else {
528                 if (__bt_get_transfer_properties(transfer_info, transfer_path) < 0) {
529                         BT_ERR("Get Properties failed");
530                         __bt_free_auth_info(agent_info.auth_info);
531                         __bt_free_transfer_info(transfer_info);
532                         agent_info.auth_info = NULL;
533                         return;
534                 }
535                 agent_info.server_type = BT_FTP_SERVER;
536         }
537
538         __bt_free_auth_info(agent_info.auth_info);
539         agent_info.auth_info = NULL;
540
541         if (agent_info.server_type == BT_CUSTOM_SERVER) {
542                 if (agent_info.custom_server == NULL) {
543                         __bt_free_transfer_info(transfer_info);
544                         return;
545                 }
546
547                 req_info = _bt_get_request_info(agent_info.accept_id);
548                 if (req_info == NULL || req_info->context == NULL) {
549                         BT_ERR("info is NULL");
550                         goto done;
551                 }
552
553                 agent_info.accept_id = 0;
554                 result = BLUETOOTH_ERROR_NONE;
555                 GArray *g_out_param1 = NULL;
556                 g_out_param1 = g_array_new(FALSE, FALSE, sizeof(gchar));
557                 if (out_param1 == NULL) {
558                         out_param1 = g_variant_new_from_data((const GVariantType *)"ay",
559                                         g_out_param1->data, g_out_param1->len,
560                                         TRUE, NULL, NULL);
561                 }
562
563                 g_dbus_method_invocation_return_value(req_info->context,
564                                 g_variant_new("(iv)", result, out_param1));
565                 g_array_free(g_out_param1, TRUE);
566                 _bt_delete_request_list(req_info->req_id);
567         }
568 done:
569         transfers = g_slist_append(transfers, transfer_info);
570
571         BT_DBG("Transfer id %d\n", transfer_info->transfer_id);
572         param = g_variant_new("(isstii)", result,
573                                 transfer_info->filename,
574                                 transfer_info->type,
575                                 transfer_info->file_size,
576                                 transfer_info->transfer_id,
577                                 agent_info.server_type);
578         _bt_send_event(BT_OPP_SERVER_EVENT,
579                 BLUETOOTH_EVENT_OBEX_SERVER_TRANSFER_STARTED,
580                 param);
581 }
582
583 void _bt_obex_transfer_progress(const char *transfer_path,
584                                         int transferred)
585 {
586         BT_DBG("+");
587         bt_transfer_info_t *transfer_info;
588         int progress = 0;
589         GVariant *param = NULL;
590         int result = BLUETOOTH_ERROR_NONE;
591
592         transfer_info = __bt_find_transfer_by_path(transfer_path);
593         ret_if(transfer_info == NULL);
594
595         progress = (int)(((gdouble)transferred /
596                         (gdouble)transfer_info->file_size) * 100);
597
598         param = g_variant_new("(isstiii)", result,
599                                 transfer_info->filename,
600                                 transfer_info->type,
601                                 transfer_info->file_size,
602                                 transfer_info->transfer_id,
603                                 progress,
604                                 agent_info.server_type);
605         _bt_send_event(BT_OPP_SERVER_EVENT,
606                 BLUETOOTH_EVENT_OBEX_SERVER_TRANSFER_PROGRESS,
607                 param);
608         BT_DBG("-");
609 }
610
611 void _bt_obex_transfer_completed(const char *transfer_path, gboolean success)
612 {
613         bt_transfer_info_t *transfer_info;
614         GVariant *param = NULL;
615         int result;
616         BT_DBG("Transfer [%s] Success [%d] \n", transfer_path, success);
617
618         result = (success == TRUE) ? BLUETOOTH_ERROR_NONE
619                                 : BLUETOOTH_ERROR_CANCEL;
620
621         transfer_info = __bt_find_transfer_by_path(transfer_path);
622
623         if (transfer_info == NULL) {
624                 BT_DBG("Very small files receiving case, did not get Active status from obexd");
625                 if (agent_info.auth_info == NULL ||
626                                 g_strcmp0(transfer_path,
627                                 agent_info.auth_info->transfer_path) != 0) {
628                         BT_ERR("auth_info is NULL, returning");
629                         return;
630                 }
631
632                 transfer_info = g_new0(bt_transfer_info_t, 1);
633
634                 transfer_info->filename = g_strdup(agent_info.auth_info->filename);
635                 transfer_info->file_size = agent_info.auth_info->file_size;
636                 transfer_info->type = g_strdup(TRANSFER_PUT);
637                 transfer_info->path = g_strdup(agent_info.auth_info->transfer_path);
638                 transfer_info->device_name = g_strdup(agent_info.auth_info->device_name);
639                 transfer_info->transfer_id = __bt_get_transfer_id(transfer_path);
640                 transfer_info->file_path = agent_info.auth_info->file_path;
641
642                 param = g_variant_new("(isstii)", result,
643                                         transfer_info->filename,
644                                         transfer_info->type,
645                                         transfer_info->file_size,
646                                         transfer_info->transfer_id,
647                                         agent_info.server_type);
648                 _bt_send_event(BT_OPP_SERVER_EVENT,
649                         BLUETOOTH_EVENT_OBEX_SERVER_TRANSFER_STARTED,
650                         param);
651         }
652         param = g_variant_new("(isssstii)", result,
653                                 transfer_info->filename,
654                                 transfer_info->type,
655                                 transfer_info->device_name,
656                                 transfer_info->file_path,
657                                 transfer_info->file_size,
658                                 transfer_info->transfer_id,
659                                 agent_info.server_type);
660         _bt_send_event(BT_OPP_SERVER_EVENT,
661                 BLUETOOTH_EVENT_OBEX_SERVER_TRANSFER_COMPLETED,
662                 param);
663         transfers = g_slist_remove(transfers, transfer_info);
664         __bt_free_transfer_info(transfer_info);
665 }
666
667 void _bt_obex_transfer_connected()
668 {
669         BT_DBG("+");
670
671         int result = BLUETOOTH_ERROR_NONE;
672         GVariant *param = NULL;
673
674         param = g_variant_new("(i)", result);
675
676         _bt_send_event(BT_OPP_SERVER_EVENT,
677                 BLUETOOTH_EVENT_OBEX_SERVER_TRANSFER_CONNECTED,
678                 param);
679         BT_DBG("-");
680 }
681
682 void _bt_obex_transfer_disconnected()
683 {
684         BT_DBG("+");
685
686         int result = BLUETOOTH_ERROR_NONE;
687         GVariant *param = NULL;
688
689         param = g_variant_new("(i)", result);
690         _bt_send_event(BT_OPP_SERVER_EVENT,
691                 BLUETOOTH_EVENT_OBEX_SERVER_TRANSFER_DISCONNECTED,
692                 param);
693         BT_DBG("-");
694 }
695
696 int _bt_register_obex_server(void)
697 {
698         GDBusConnection *g_conn;
699         GDBusProxy *manager_proxy;
700         GError *g_error = NULL;
701
702         /* Get the session bus. */
703         g_conn = _bt_get_session_gconn();
704         retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
705
706         _bt_obex_agent_new(BT_OBEX_SERVER_AGENT_PATH);
707
708         _bt_obex_setup(BT_OBEX_SERVER_AGENT_PATH);
709
710         _bt_obex_set_authorize_cb(BT_OBEX_SERVER_AGENT_PATH,
711                                         __bt_authorize_cb, NULL);
712
713         manager_proxy = g_dbus_proxy_new_sync(g_conn, G_DBUS_PROXY_FLAGS_NONE,
714                                                 NULL, BT_OBEX_SERVICE,
715                                                 BT_OBEX_PATH,
716                                                 BT_OBEX_MANAGER,
717                                                 NULL, &g_error);
718
719         if (manager_proxy == NULL) {
720                 return BLUETOOTH_ERROR_INTERNAL;
721         }
722
723         g_dbus_proxy_call_sync(manager_proxy, "RegisterAgent",
724                                 g_variant_new("(o)", BT_OBEX_SERVER_AGENT_PATH),
725                                 G_DBUS_CALL_FLAGS_NONE,
726                                 DBUS_TIMEOUT, NULL,
727                                 &g_error);
728
729         if (g_error != NULL) {
730                 BT_ERR("Agent registration failed: %s\n", g_error->message);
731                 g_object_unref(manager_proxy);
732                 g_error_free(g_error);
733                 return BLUETOOTH_ERROR_INTERNAL;
734         }
735
736         agent_info.proxy = manager_proxy;
737
738         return BLUETOOTH_ERROR_NONE;
739 }
740
741 int _bt_unregister_obex_server(void)
742 {
743         GError *g_error = NULL;
744
745         retv_if(agent_info.proxy == NULL,
746                                 BLUETOOTH_ERROR_INTERNAL);
747
748         g_dbus_proxy_call_sync(agent_info.proxy, "UnregisterAgent",
749                                 g_variant_new("(o)", BT_OBEX_SERVER_AGENT_PATH),
750                                 G_DBUS_CALL_FLAGS_NONE,
751                                 DBUS_TIMEOUT, NULL,
752                                 &g_error);
753         if (g_error != NULL) {
754                 BT_ERR("Agent unregistration failed: %s", g_error->message);
755                 g_error_free(g_error);
756         }
757         _bt_obex_agent_destroy(BT_OBEX_SERVER_AGENT_PATH);
758         g_object_unref(agent_info.proxy);
759         agent_info.proxy = NULL;
760
761         return BLUETOOTH_ERROR_NONE;
762 }
763
764 gboolean __bt_check_folder_path(const char *dest_path)
765 {
766         DIR *dp;
767
768         retv_if(dest_path == NULL, FALSE);
769
770         dp = opendir(dest_path);
771
772         if (dp == NULL) {
773                 BT_ERR("The directory does not exist");
774                 return FALSE;
775         }
776
777         closedir(dp);
778
779         return TRUE;
780 }
781
782 int _bt_obex_server_allocate(char *sender, const char *dest_path, int app_pid, gboolean is_native)
783 {
784         BT_DBG("+");
785         if (__bt_check_folder_path(dest_path) == FALSE)
786                 return BLUETOOTH_ERROR_INVALID_PARAM;
787
788         if (is_native == TRUE) {
789                 retv_if(agent_info.native_server,
790                                 BLUETOOTH_ERROR_DEVICE_BUSY);
791
792                 /* Force to change the control to native */
793                 agent_info.native_server = g_malloc0(sizeof(bt_server_info_t));
794                 agent_info.native_server->dest_path = g_strdup(dest_path);
795                 agent_info.native_server->sender = g_strdup(sender);
796                 agent_info.native_server->app_pid = app_pid;
797                 agent_info.server_type = BT_NATIVE_SERVER;
798                 _bt_unregister_osp_server_in_agent(BT_OBEX_SERVER, NULL);
799         } else {
800                 retv_if(agent_info.custom_server,
801                                 BLUETOOTH_ERROR_DEVICE_BUSY);
802
803                 /* Force to change the control to custom */
804                 agent_info.custom_server = g_malloc0(sizeof(bt_server_info_t));
805                 agent_info.custom_server->dest_path = g_strdup(dest_path);
806                 agent_info.custom_server->sender = g_strdup(sender);
807                 agent_info.custom_server->app_pid = app_pid;
808                 agent_info.server_type = BT_CUSTOM_SERVER;
809                 _bt_register_osp_server_in_agent(BT_OBEX_SERVER, NULL, NULL, -1);
810         }
811         BT_DBG("-");
812         return BLUETOOTH_ERROR_NONE;
813 }
814
815 int _bt_obex_server_deallocate(int app_pid, gboolean is_native)
816 {
817         if (is_native == TRUE) {
818                 retv_if(agent_info.native_server == NULL,
819                                 BLUETOOTH_ERROR_AGENT_DOES_NOT_EXIST);
820
821                 retv_if(agent_info.native_server->app_pid != app_pid,
822                                 BLUETOOTH_ERROR_ACCESS_DENIED);
823
824                 __bt_free_server_info(agent_info.native_server);
825                 agent_info.native_server = NULL;
826
827                 /* Change the control to custom */
828                 if (agent_info.custom_server) {
829                         agent_info.server_type = BT_CUSTOM_SERVER;
830                         _bt_register_osp_server_in_agent(BT_OBEX_SERVER,
831                                                         NULL, NULL, -1);
832                 }
833         } else {
834                 retv_if(agent_info.custom_server == NULL,
835                                 BLUETOOTH_ERROR_AGENT_DOES_NOT_EXIST);
836
837                 retv_if(agent_info.custom_server->app_pid != app_pid,
838                                 BLUETOOTH_ERROR_ACCESS_DENIED);
839
840                 __bt_free_server_info(agent_info.custom_server);
841                 agent_info.custom_server = NULL;
842
843                 _bt_unregister_osp_server_in_agent(BT_OBEX_SERVER, NULL);
844
845                 /* Change the control to native */
846                 if (agent_info.native_server)
847                         agent_info.server_type = BT_NATIVE_SERVER;
848         }
849
850         return BLUETOOTH_ERROR_NONE;
851 }
852
853 int _bt_obex_server_accept_authorize(const char *filename, gboolean is_native)
854 {
855         char file_path[BT_FILE_PATH_MAX] = { 0 };
856         bt_server_info_t *server_info;
857
858         BT_CHECK_PARAMETER(filename, return);
859
860         retv_if(agent_info.auth_info == NULL, BLUETOOTH_ERROR_INTERNAL);
861
862         retv_if(agent_info.auth_info->reply_context == NULL,
863                                 BLUETOOTH_ERROR_INTERNAL);
864
865         if (is_native == TRUE)
866                 server_info = agent_info.native_server;
867         else
868                 server_info = agent_info.custom_server;
869
870         retv_if(server_info == NULL, BLUETOOTH_ERROR_INTERNAL);
871
872         if (server_info->dest_path != NULL)
873                 snprintf(file_path, sizeof(file_path), "%s/%s",
874                         server_info->dest_path, filename);
875         else
876                 snprintf(file_path, sizeof(file_path), "%s", filename);
877
878         g_dbus_method_invocation_return_value(agent_info.auth_info->reply_context,
879                 g_variant_new("(s)",&file_path));
880         agent_info.auth_info->reply_context = NULL;
881         agent_info.auth_info->file_path = g_strdup(file_path);
882
883         return BLUETOOTH_ERROR_NONE;
884 }
885
886 int _bt_obex_server_reject_authorize(void)
887 {
888         GError *g_error;
889
890         retv_if(agent_info.auth_info->reply_context == NULL,
891                                 BLUETOOTH_ERROR_INTERNAL);
892
893         g_error = g_error_new(__bt_obex_error_quark(),
894                         BT_OBEX_AGENT_ERROR_CANCEL,
895                         "CancelledByUser");
896
897         g_dbus_method_invocation_return_gerror(agent_info.auth_info->reply_context,
898                         g_error);
899         g_error_free(g_error);
900
901         __bt_free_auth_info(agent_info.auth_info);
902         agent_info.auth_info = NULL;
903
904         return BLUETOOTH_ERROR_NONE;
905 }
906
907 int _bt_obex_server_set_destination_path(const char *dest_path,
908                                                 gboolean is_native)
909 {
910         bt_server_info_t *server_info;
911
912         BT_CHECK_PARAMETER(dest_path, return);
913
914         DIR *dp = NULL;
915
916         dp = opendir(dest_path);
917
918         if (dp == NULL) {
919                 BT_ERR("The directory does not exist");
920                 return BLUETOOTH_ERROR_INVALID_PARAM;
921         }
922
923         closedir(dp);
924
925         if (is_native == TRUE)
926                 server_info = agent_info.native_server;
927         else
928                 server_info = agent_info.custom_server;
929
930         retv_if(server_info == NULL,
931                         BLUETOOTH_ERROR_AGENT_DOES_NOT_EXIST);
932
933         g_free(server_info->dest_path);
934         server_info->dest_path = g_strdup(dest_path);
935
936         return BLUETOOTH_ERROR_NONE;
937 }
938
939 int _bt_obex_server_set_root(const char *root)
940 {
941         GError *g_error = NULL;
942         GVariant *folder = NULL;
943         char *string = "Root";
944         DIR *dp = NULL;
945
946         BT_CHECK_PARAMETER(root, return);
947
948         retv_if(agent_info.proxy == NULL,
949                                 BLUETOOTH_ERROR_INTERNAL);
950
951         dp = opendir(root);
952
953         if (dp == NULL) {
954                 BT_ERR("The directory does not exist");
955                 return BLUETOOTH_ERROR_INVALID_PARAM;
956         }
957
958         closedir(dp);
959
960         folder = g_variant_new_string(root);
961         g_dbus_proxy_call_sync(agent_info.proxy, "SetProperty",
962                         g_variant_new("(sv)", string, folder),
963                         G_DBUS_CALL_FLAGS_NONE,
964                         DBUS_TIMEOUT, NULL,
965                         &g_error);
966
967         if (g_error) {
968                 BT_ERR("SetProperty Fail: %s", g_error->message);
969                 g_error_free(g_error);
970                 return BLUETOOTH_ERROR_INTERNAL;
971         }
972
973         return BLUETOOTH_ERROR_NONE;
974 }
975
976 int _bt_obex_server_cancel_transfer(int transfer_id)
977 {
978         bt_transfer_info_t *transfer = NULL;
979         GDBusProxy *proxy;
980         GError *err = NULL;
981         BT_DBG("+");
982         transfer = __bt_find_transfer_by_id(transfer_id);
983
984         retv_if(transfer == NULL, BLUETOOTH_ERROR_NOT_FOUND);
985         proxy = __bt_get_transfer_proxy(transfer->path);
986
987         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
988
989         g_dbus_proxy_call_sync(proxy, "Cancel", NULL,
990                 G_DBUS_CALL_FLAGS_NONE,
991                 DBUS_TIMEOUT, NULL, &err);
992         if (err) {
993                 BT_ERR("Dbus Err: %s", err->message);
994                 g_clear_error(&err);
995         }
996         g_object_unref(proxy);
997
998         return BLUETOOTH_ERROR_NONE;
999 }
1000
1001 int _bt_obex_server_cancel_all_transfers(void)
1002 {
1003         GSList *l;
1004         bt_transfer_info_t *transfer;
1005
1006         for (l = transfers; l != NULL; l = l->next) {
1007                 transfer = l->data;
1008
1009                 if (transfer == NULL)
1010                         continue;
1011
1012                 _bt_obex_server_cancel_transfer(transfer->transfer_id);
1013         }
1014
1015         return BLUETOOTH_ERROR_NONE;
1016 }
1017
1018 int _bt_obex_server_is_activated(gboolean *activated)
1019 {
1020         BT_CHECK_PARAMETER(activated, return);
1021
1022         if (agent_info.custom_server) {
1023                 *activated = TRUE;
1024         } else {
1025                 *activated = FALSE;
1026         }
1027
1028         return BLUETOOTH_ERROR_NONE;
1029 }
1030
1031 int _bt_obex_server_check_allocation(gboolean *allocation)
1032 {
1033         BT_CHECK_PARAMETER(allocation, return);
1034
1035         if (agent_info.native_server || agent_info.custom_server) {
1036                 *allocation = TRUE;
1037         } else {
1038                 *allocation = FALSE;
1039         }
1040
1041         return BLUETOOTH_ERROR_NONE;
1042 }
1043
1044 int _bt_obex_server_check_termination(char *sender)
1045 {
1046         BT_CHECK_PARAMETER(sender, return);
1047
1048         if (agent_info.native_server) {
1049                 if (g_strcmp0(sender, agent_info.native_server->sender) == 0) {
1050                         _bt_obex_server_deallocate(agent_info.native_server->app_pid,
1051                                                 TRUE);
1052                 }
1053         }
1054
1055         if (agent_info.custom_server) {
1056                 if (g_strcmp0(sender, agent_info.custom_server->sender) == 0) {
1057                         _bt_obex_server_deallocate(agent_info.custom_server->app_pid,
1058                                                 FALSE);
1059                 }
1060         }
1061
1062         return BLUETOOTH_ERROR_NONE;
1063 }
1064
1065 int _bt_obex_server_is_receiving(gboolean *receiving)
1066 {
1067         BT_CHECK_PARAMETER(receiving, return);
1068
1069         if (transfers == NULL || g_slist_length(transfers) == 0) {
1070                 *receiving = FALSE;
1071         } else {
1072                 *receiving = TRUE;
1073         }
1074
1075         return BLUETOOTH_ERROR_NONE;
1076 }
1077
1078 gboolean __bt_obex_server_accept_timeout_cb(gpointer user_data)
1079 {
1080         request_info_t *req_info;
1081         GVariant *out_param1 = NULL;
1082         int result = BLUETOOTH_ERROR_TIMEOUT;
1083
1084         /* Already reply in _bt_obex_transfer_started */
1085         retv_if(agent_info.accept_id == 0, FALSE);
1086
1087         req_info = _bt_get_request_info(agent_info.accept_id);
1088         if (req_info == NULL || req_info->context == NULL) {
1089                 BT_ERR("info is NULL");
1090                 return FALSE;
1091         }
1092
1093         agent_info.accept_id = 0;
1094         GArray *g_out_param1 = NULL;
1095         g_out_param1 = g_array_new(FALSE, FALSE, sizeof(gchar));
1096         if (out_param1 == NULL) {
1097                 out_param1 = g_variant_new_from_data((const GVariantType *)"ay",
1098                                 g_out_param1->data, g_out_param1->len,
1099                                 TRUE, NULL, NULL);
1100         }
1101
1102         g_dbus_method_invocation_return_value(req_info->context,
1103                         g_variant_new("(iv)", result, out_param1));
1104         g_array_free(g_out_param1, TRUE);
1105         _bt_delete_request_list(req_info->req_id);
1106
1107         return FALSE;
1108 }
1109
1110 /* To support the BOT  */
1111 int _bt_obex_server_accept_connection(int request_id)
1112 {
1113         if (!_bt_agent_reply_authorize(TRUE))
1114                 return BLUETOOTH_ERROR_INTERNAL;
1115
1116         agent_info.accept_id = request_id;
1117
1118         g_timeout_add(BT_SERVER_ACCEPT_TIMEOUT,
1119                         (GSourceFunc)__bt_obex_server_accept_timeout_cb,
1120                         NULL);
1121
1122         return BLUETOOTH_ERROR_NONE;
1123 }
1124
1125 /* To support the BOT  */
1126 int _bt_obex_server_reject_connection(void)
1127 {
1128         if (!_bt_agent_reply_authorize(FALSE))
1129                 return BLUETOOTH_ERROR_INTERNAL;
1130
1131         return BLUETOOTH_ERROR_NONE;
1132 }
1133