40f077432aa86716bdc06f801583c51be0516ca2
[platform/core/connectivity/bluetooth-frwk.git] / lib / obex.c
1 /*
2 * Bluetooth-Frwk-NG
3 *
4 * Copyright (c) 2013-2014 Intel Corporation.
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 <stdlib.h>
21 #include <string.h>
22 #include <errno.h>
23 #include <gio/gio.h>
24 #include "common.h"
25 #include "obex.h"
26
27 #define OBEX_NAME "org.bluez.obex"
28
29 #define OBJECT_MANAGE_PATH "/"
30
31 #define OBJECT_OBEX_PATH "/org/bluez/obex"
32
33 #define OBEX_AGENT_INTERFACE "org.bluez.obex.AgentManager1"
34
35 #define PROPERTIES_INTERFACE "org.freedesktop.DBus.Properties"
36
37 #define MANAGER_INTERFACE "org.freedesktop.DBus.ObjectManager"
38
39 #define OBEX_SESSION_INTERFACE "org.bluez.obex.Session1"
40
41 #define OBEX_TRANSFER_INTERFACE "org.bluez.obex.Transfer1"
42
43 static GDBusConnection *g_connection;
44 static int g_opp_startup;
45 static GDBusProxy *manager_proxy;
46 static GDBusObjectManager *object_manager;
47
48 static obex_agent_added_cb_t obex_agent_added_cb;
49 static void *obex_agent_added_cb_data;
50
51 static GDBusConnection *_obex_get_session_dbus(void)
52 {
53         GError *error = NULL;
54
55         if (g_connection)
56                 return g_connection;
57
58         g_connection =
59                 g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, &error);
60         if (g_connection == NULL) {
61                 DBG("%s", error->message);
62                 g_error_free(error);
63         }
64
65         return g_connection;
66 }
67
68 void obex_agent_set_agent_added(obex_agent_added_cb_t cb, void *user_data)
69 {
70         obex_agent_added_cb = cb;
71         obex_agent_added_cb_data = user_data;
72 }
73
74 void obex_agent_unset_agent_added(void)
75 {
76         obex_agent_added_cb = NULL;
77         obex_agent_added_cb_data = NULL;
78 }
79
80 struct agent_data {
81         agent_cb_t cb;
82         void *user_data;
83         GDBusConnection *conn;
84 };
85
86 static void agent_callback(GObject *source_object,
87                                         GAsyncResult *res,
88                                         gpointer user_data)
89 {
90         GVariant *ret;
91         GError *error = NULL;
92         enum bluez_error_type error_type = ERROR_NONE;
93         struct agent_data *agent_data = user_data;
94
95         DBG("+");
96
97         ret = g_dbus_connection_call_finish(agent_data->conn,
98                                                 res, &error);
99         if (ret == NULL) {
100                 error_type = get_error_type(error);
101                 ERROR("error = %d", error_type);
102                 g_free(error);
103         }
104
105         agent_data->cb(error_type, agent_data->user_data);
106
107         g_free(agent_data);
108
109         DBG("-");
110 }
111
112 void obex_agent_register_agent(const char *agent_path,
113                                 agent_cb_t cb,
114                                 void *user_data)
115 {
116         struct agent_data *register_data;
117         GDBusConnection *connection = _obex_get_session_dbus();
118
119         DBG("");
120
121         register_data = g_new0(struct agent_data, 1);
122         if (register_data == NULL) {
123                 ERROR("no memory");
124                 return;
125         }
126
127         register_data->cb = cb;
128         register_data->user_data = user_data;
129         register_data->conn = connection;
130
131         if (g_opp_startup)
132                 g_dbus_connection_call(connection, "org.bluez.obex",
133                                         "/org/bluez/obex",
134                                         "org.bluez.obex.AgentManager1",
135                                         "RegisterAgent",
136                                         g_variant_new("(o)", agent_path),
137                                         NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL,
138                                         agent_callback, register_data);
139         else
140                 ERROR("agent not registered");
141 }
142
143 void obex_agent_unregister_agent(const char *agent_path,
144                                         agent_cb_t cb,
145                                         void *user_data)
146 {
147         struct agent_data *unregister_data;
148         GDBusConnection *connection = _obex_get_session_dbus();
149
150         DBG("");
151
152         unregister_data = g_new0(struct agent_data, 1);
153         if (unregister_data == NULL) {
154                 ERROR("no memory");
155                 return;
156         }
157
158         unregister_data->cb = cb;
159         unregister_data->user_data = user_data;
160
161         if (g_opp_startup)
162                 g_dbus_connection_call(connection, "org.bluez.obex",
163                                         "/org/bluez/obex",
164                                         "org.bluez.obex.AgentManager1",
165                                         "UnregisterAgent",
166                                         g_variant_new("(o)", agent_path),
167                                         NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL,
168                                         agent_callback, unregister_data);
169         else
170                 ERROR("agent not registered");
171 }
172
173 static enum transfer_state get_transfer_state_from_string(const char *string)
174 {
175         if (string == NULL)
176                 return OBEX_TRANSFER_UNKNOWN;
177
178         if (!g_strcmp0(string, "queued"))
179                 return OBEX_TRANSFER_QUEUED;
180
181         if (!g_strcmp0(string, "active"))
182                 return OBEX_TRANSFER_ACTIVE;
183
184         if (!g_strcmp0(string, "complete"))
185                 return OBEX_TRANSFER_COMPLETE;
186
187         if (!g_strcmp0(string, "error"))
188                 return OBEX_TRANSFER_ERROR;
189
190         return OBEX_TRANSFER_UNKNOWN;
191 }
192
193 enum transfer_state obex_transfer_get_property_state(const char *path)
194 {
195         GDBusProxy *p_proxy;
196         char *status = NULL;
197
198         DBG("");
199
200         p_proxy = g_dbus_proxy_new_for_bus_sync(
201                                         G_BUS_TYPE_SESSION, 0,
202                                         NULL,
203                                         "org.bluez.obex",
204                                         path,
205                                         PROPERTIES_INTERFACE,
206                                         NULL, NULL);
207
208         if (p_proxy)
209                 status = property_get_string(p_proxy,
210                                 OBEX_TRANSFER_INTERFACE, "Status");
211
212         g_object_unref(p_proxy);
213
214         return get_transfer_state_from_string(status);
215 }
216
217 int obex_transfer_get_property_transferred(const char *path,
218                                 guint64 *u64)
219 {
220         GDBusProxy *p_proxy;
221         int ret = -1;
222
223         DBG("");
224
225         p_proxy = g_dbus_proxy_new_for_bus_sync(
226                                         G_BUS_TYPE_SESSION, 0,
227                                         NULL,
228                                         "org.bluez.obex",
229                                         path,
230                                         PROPERTIES_INTERFACE,
231                                         NULL, NULL);
232
233         if (p_proxy)
234                 ret = property_get_uint64(p_proxy,
235                         OBEX_TRANSFER_INTERFACE, "Transferred", u64);
236
237         g_object_unref(p_proxy);
238
239         return ret;
240 }
241
242 int obex_transfer_get_property_size(const char *path,
243                                 guint64 *u64)
244 {
245         GDBusProxy *p_proxy;
246         int ret = -1;
247
248         DBG("path = %s", path);
249         p_proxy = g_dbus_proxy_new_for_bus_sync(
250                                         G_BUS_TYPE_SESSION, 0,
251                                         NULL,
252                                         "org.bluez.obex",
253                                         path,
254                                         PROPERTIES_INTERFACE,
255                                         NULL, NULL);
256
257         if (p_proxy)
258                 ret = property_get_uint64(p_proxy,
259                         OBEX_TRANSFER_INTERFACE, "Size", u64);
260
261         g_object_unref(p_proxy);
262
263         return ret;
264 }
265
266 static void parse_object(gpointer data, gpointer user_data)
267 {
268         GDBusObject *obj = data;
269         const char *path = g_dbus_object_get_object_path(obj);
270
271
272         DBG("object path name %s", path);
273
274         if (!g_strcmp0(path, OBJECT_OBEX_PATH)) {
275                 if (g_opp_startup == 1)
276                         return;
277                 g_opp_startup = 1;
278                 if (obex_agent_added_cb)
279                         obex_agent_added_cb(obex_agent_added_cb_data);
280         }
281
282         return;
283 }
284
285
286 static void interfaces_removed(GVariant *parameters)
287 {
288         gchar *object_path;
289         GVariantIter *iter;
290
291         gchar *parameters_s = g_variant_print(parameters, TRUE);
292
293         g_variant_get(parameters, "(oas)", &object_path, &iter);
294
295         DBG("%s", parameters_s);
296
297         g_free(parameters_s);
298
299         DBG("%s", object_path);
300
301         if (!g_strcmp0(object_path, OBJECT_OBEX_PATH))
302                 g_opp_startup = 0;
303 }
304
305 static void interfaces_added(GVariant *parameters)
306 {
307         gchar *object_path;
308         GDBusObject *obj;
309
310         g_variant_get(parameters, "(oa{sa{sv}})", &object_path, NULL);
311
312         DBG("object %s", object_path);
313
314         obj = g_dbus_object_manager_get_object(object_manager, object_path);
315
316         if (obj)
317                 parse_object(obj, NULL);
318 }
319
320 static gboolean handle_interfaces_added(gpointer user_data)
321 {
322         GVariant *parameters = user_data;
323
324         interfaces_added(parameters);
325
326         g_variant_unref(parameters);
327
328         return FALSE;
329 }
330
331 static void interfaces_changed(GDBusProxy *proxy,
332                                 gchar *sender_name,
333                                 gchar *signal_name,
334                                 GVariant *parameters,
335                                 gpointer user_data)
336 {
337         if (!g_strcmp0(signal_name, "InterfacesAdded"))
338                 g_idle_add(handle_interfaces_added,
339                                 g_variant_ref_sink(parameters));
340         if (!g_strcmp0(signal_name, "InterfacesRemoved"))
341                 interfaces_removed(parameters);
342 }
343
344 int obex_agent_get_agent(void)
345 {
346         return g_opp_startup;
347 }
348
349 int obex_lib_init(void)
350 {
351         GList *obj_list;
352
353         DBG("");
354
355         if (object_manager != NULL)
356                 return 0;
357
358         manager_proxy = g_dbus_proxy_new_for_bus_sync(
359                                                 G_BUS_TYPE_SESSION, 0,
360                                                 NULL,
361                                                 OBEX_NAME,
362                                                 "/",
363                                                 MANAGER_INTERFACE,
364                                                 NULL, NULL);
365
366         if (manager_proxy == NULL)
367                 ERROR("create manager_proxy error");
368         else {
369                 DBG("manager proxy 0x%p created", manager_proxy);
370
371                 g_signal_connect(manager_proxy,
372                                 "g-signal",
373                                 G_CALLBACK(interfaces_changed),
374                                 NULL);
375         }
376
377         object_manager = g_dbus_object_manager_client_new_for_bus_sync(
378                                                         G_BUS_TYPE_SESSION,
379                                                         0,
380                                                         OBEX_NAME,
381                                                         OBJECT_MANAGE_PATH,
382                                                         NULL, NULL, NULL,
383                                                         NULL, NULL);
384
385         if (object_manager == NULL) {
386                 ERROR("create object manager error");
387                 /* TODO: define error type */
388                 return -1;
389         }
390
391         DBG("object manager %p is created", object_manager);
392
393         obj_list = g_dbus_object_manager_get_objects(object_manager);
394
395         g_list_foreach(obj_list, parse_object, NULL);
396
397         return 0;
398 }
399
400 static void destruct_obex_object_manager(void)
401 {
402         DBG("");
403
404         g_object_unref(object_manager);
405
406         object_manager = NULL;
407 }
408
409 void obex_lib_deinit(void)
410 {
411         DBG("");
412
413         if (manager_proxy)
414                 g_object_unref(manager_proxy);
415
416         destruct_obex_object_manager();
417 }
418
419 struct obex_session_result {
420         obex_session_state_cb cb;
421         void *user_data;
422         GDBusConnection *conn;
423 };
424
425 static const char *get_obex_target_string(enum obex_target target)
426 {
427         switch (target) {
428         case OBEX_TARGET_UNKNOWN:
429                 return NULL;
430         case OBEX_FTP:
431                 return "ftp";
432         case OBEX_MAP:
433                 return "map";
434         case OBEX_OPP:
435                 return "opp";
436         case OBEX_PBAP:
437                 return "pbap";
438         case OBEX_SYNC:
439                 return "sync";
440         default:
441                 return NULL;
442         }
443
444         return NULL;
445 }
446
447 static void create_session_cb(GObject *object,
448                                 GAsyncResult *res,
449                                 gpointer user_data)
450 {
451         GError *error;
452         char *session;
453         GVariant *result;
454         struct obex_session_result *async_node;
455
456         error = NULL;
457         async_node = user_data;
458
459         DBG("+");
460
461         result = g_dbus_connection_call_finish(async_node->conn,
462                                                 res, &error);
463
464         if (error) {
465                 ERROR("create session error %s", error->message);
466
467                 async_node->cb(NULL, NULL, OBEX_SESSION_FAILED,
468                                         async_node->user_data,
469                                         g_strdup(error->message));
470
471                 g_error_free(error);
472         } else {
473
474                 g_variant_get(result, "(o)", &session);
475
476                 DBG("Sesseion created %s", session);
477
478                 async_node->cb(NULL, session, OBEX_SESSION_CREATED,
479                                         async_node->user_data, NULL);
480
481                 g_free(session);
482
483                 g_variant_unref(result);
484         }
485
486         g_free(async_node);
487
488         DBG("-");
489 }
490
491 static void remove_session_cb(GObject *object,
492                                 GAsyncResult *res,
493                                 gpointer user_data)
494 {
495         GError *error;
496         GVariant *result;
497         GDBusConnection *conn = user_data;
498
499         DBG("");
500
501         error = NULL;
502         result = g_dbus_connection_call_finish(conn, res, &error);
503
504         if (error) {
505                 ERROR("create session error %s", error->message);
506
507                 g_error_free(error);
508         } else
509                 g_variant_unref(result);
510 }
511
512 int obex_create_session(const char *destination,
513                                 enum obex_target target,
514                                 obex_session_state_cb cb,
515                                 void *data)
516 {
517         GVariantBuilder *builder;
518         const char *target_s;
519         GVariant *target_v;
520         struct obex_session_result *async_node;
521         GDBusConnection *connection = _obex_get_session_dbus();
522
523         DBG("+");
524
525         if (!connection)
526                 return -1;
527
528         async_node = g_new0(struct obex_session_result, 1);
529         if (async_node == NULL) {
530                 ERROR("no memory");
531                 return -1;
532         }
533
534         async_node->cb = cb;
535         async_node->user_data = data;
536         async_node->conn = connection;
537
538         target_s = get_obex_target_string(target);
539         target_v = g_variant_new("s", target_s);
540         builder = g_variant_builder_new(G_VARIANT_TYPE_ARRAY);
541         g_variant_builder_add(builder, "{sv}", "Target", target_v);
542
543         DBG("destination = %s, target_s = %s", destination, target_s);
544
545         g_dbus_connection_call(connection, "org.bluez.obex",
546                                         "/org/bluez/obex",
547                                         "org.bluez.obex.Client1",
548                                         "CreateSession",
549                                         g_variant_new("(sa{sv})",
550                                         destination, builder),
551                                         NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL,
552                                         create_session_cb, async_node);
553
554         g_variant_builder_unref(builder);
555
556         DBG("-");
557
558         return 0;
559 }
560
561 void obex_session_remove_session(const char *object_path)
562 {
563         GDBusConnection *connection = _obex_get_session_dbus();
564
565         DBG("");
566
567         if (!connection)
568                 return;
569
570         g_dbus_connection_call(connection, "org.bluez.obex",
571                                 "/org/bluez/obex",
572                                 "org.bluez.obex.Client1",
573                                 "RemoveSession",
574                                 g_variant_new("(o)", object_path),
575                                 NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL,
576                                 remove_session_cb, connection);
577 }
578
579 struct obex_transfer_result {
580         obex_transfer_state_cb cb;
581         void *user_data;
582         GDBusConnection *conn;
583 };
584
585 static void create_transfer_cb(GObject *object,
586                                 GAsyncResult *res,
587                                 gpointer user_data)
588 {
589         GError *error = NULL;
590         char *transfer;
591         GVariant *result;
592         struct obex_transfer_result *async_node = user_data;
593
594         DBG("+");
595
596         result = g_dbus_connection_call_finish(async_node->conn,
597                                                 res, &error);
598
599         async_node = user_data;
600
601         if (error) {
602                 ERROR("transfer error %s", error->message);
603
604                 async_node->cb(NULL, OBEX_TRANSFER_ERROR, NULL, 0, 0,
605                                 NULL, g_strdup(error->message));
606
607                 g_error_free(error);
608         } else {
609                 g_variant_get(result, "(oa{sv})", &transfer, NULL);
610
611                 DBG("transfer created %s", transfer);
612
613                 async_node->cb(g_strdup(transfer), OBEX_TRANSFER_QUEUED,
614                                 NULL, 0, 0, async_node->user_data, NULL);
615
616                 g_free(transfer);
617
618                 g_variant_unref(result);
619         }
620
621         g_free(async_node);
622
623         DBG("-");
624 }
625
626 void obex_session_opp_send_file(const char *session,
627                                 const char *file,
628                                 obex_transfer_state_cb cb,
629                                 void *data)
630 {
631         struct obex_transfer_result *async_node;
632         GDBusConnection *connection = _obex_get_session_dbus();
633
634         DBG("");
635
636         if (!connection)
637                 return;
638
639         async_node = g_new0(struct obex_transfer_result, 1);
640         if (async_node == NULL) {
641                 ERROR("no memory");
642                 return;
643         }
644
645         async_node->cb = cb;
646         async_node->user_data = data;
647         async_node->conn = connection;
648
649         g_dbus_connection_call(connection, "org.bluez.obex",
650                                         session,
651                                         "org.bluez.obex.ObjectPush1",
652                                         "SendFile",
653                                         g_variant_new("(s)", file),
654                                         NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL,
655                                         create_transfer_cb, async_node);
656 }
657
658 struct obex_watch_result {
659         obex_transfer_state_cb cb;
660         void *user_data;
661         char *path;
662         unsigned int proxy_id;
663         GDBusProxy *proxy;
664 };
665
666 int obex_get_transfer_id(const char *transfer_path, enum obex_role role)
667 {
668         int id;
669         char *p = g_strrstr(transfer_path, "transfer");
670
671         if (p == NULL) {
672                 ERROR("Can't get transfer id");
673                 return -1;
674         }
675
676         id = atoi(8 + p);
677
678         if (role == OBEX_SERVER)
679                 id = id + 10000;
680
681         DBG("transfer id %d", id);
682
683         return id;
684 }
685
686 static void transfer_properties_changed(GDBusProxy *proxy,
687                                         GVariant *changed_properties,
688                                         GStrv *invalidated_properties,
689                                         gpointer user_data)
690 {
691         struct obex_watch_result *async_node = user_data;
692         gchar *status;
693         enum transfer_state state;
694         gchar *name = NULL;
695         guint64 size = 0;
696         gboolean variant_found;
697         guint64 transferred = 0;
698         GDBusProxy *p_proxy;
699
700         gchar *properties = g_variant_print(changed_properties, TRUE);
701
702         DBG("properties %s", properties);
703         g_free(properties);
704
705         if (!async_node || !async_node->path)
706                 return;
707
708         p_proxy = g_dbus_proxy_new_for_bus_sync(
709                                         G_BUS_TYPE_SESSION, 0,
710                                         NULL,
711                                         "org.bluez.obex",
712                                         async_node->path,
713                                         PROPERTIES_INTERFACE,
714                                         NULL, NULL);
715
716         if (!p_proxy)
717                 return;
718
719         variant_found = g_variant_lookup(changed_properties,
720                                         "Status", "s", &status);
721
722         if (variant_found) {
723                 DBG("status = %s", status);
724                 state = get_transfer_state_from_string(status);
725                 if (state == OBEX_TRANSFER_ERROR ||
726                         state == OBEX_TRANSFER_COMPLETE)
727                         goto done;
728         } else {
729                 status = property_get_string(p_proxy,
730                         OBEX_TRANSFER_INTERFACE, "Status");
731                 state = get_transfer_state_from_string(status);
732         }
733
734         variant_found = g_variant_lookup(changed_properties,
735                                 "Transferred", "t", &transferred);
736
737         if (!variant_found)
738                 property_get_uint64(p_proxy,
739                         OBEX_TRANSFER_INTERFACE,
740                         "Transferred", &transferred);
741         name = property_get_string(p_proxy,
742                         OBEX_TRANSFER_INTERFACE, "Filename");
743
744         property_get_uint64(p_proxy,
745                         OBEX_TRANSFER_INTERFACE, "Size", &size);
746
747         DBG("state: %d, %ju, %s, %s, %ju", state, transferred,
748                                                 name, status, size);
749
750         async_node->cb(async_node->path, state, name, size,
751                         transferred, async_node->user_data, NULL);
752
753         g_object_unref(p_proxy);
754         return;
755 done:
756         DBG("state: %d, %ju, %s, %s, %ju", state, transferred,
757                                                 name, status, size);
758
759         async_node->cb(async_node->path, state, name, size, transferred,
760                                 async_node->user_data, NULL);
761
762         g_signal_handler_disconnect(async_node->proxy,
763                                                 async_node->proxy_id);
764         g_object_unref(p_proxy);
765         g_object_unref(async_node->proxy);
766         if (async_node->path)
767                 g_free(async_node->path);
768         async_node->path = NULL;
769         g_free(async_node);
770         async_node = NULL;
771 }
772
773 /* notify specific transfer */
774 int obex_transfer_set_notify(char *transfer_path,
775                                 obex_transfer_state_cb cb, void *data)
776 {
777         struct obex_watch_result *async_node;
778         GDBusProxy *proxy;
779
780         DBG("");
781
782         async_node = g_new0(struct obex_watch_result, 1);
783         if (async_node == NULL) {
784                 ERROR("no memory");
785                 return -1;
786         }
787
788         DBG("transfer_path = %s", transfer_path);
789         proxy = g_dbus_proxy_new_for_bus_sync(
790                                         G_BUS_TYPE_SESSION, 0,
791                                         NULL,
792                                         "org.bluez.obex",
793                                         transfer_path,
794                                         "org.bluez.obex.Transfer1",
795                                         NULL, NULL);
796
797         if (proxy == NULL) {
798                 g_free(async_node);
799                 WARN("properties proxy error");
800                 return -1;
801         }
802
803         async_node->cb = cb;
804         async_node->user_data = data;
805         async_node->proxy = g_object_ref(proxy);
806         async_node->path = g_strdup(transfer_path);
807
808         async_node->proxy_id = g_signal_connect(async_node->proxy,
809                         "g-properties-changed",
810                         G_CALLBACK(transfer_properties_changed),
811                         async_node);
812
813         return 0;
814 }
815
816 static void simple_cancle_cb(GObject *object,
817                         GAsyncResult *res, gpointer user_data)
818 {
819         GError *error;
820         GVariant *result;
821         GDBusConnection *conn = user_data;
822
823         DBG("");
824
825         error = NULL;
826         result = g_dbus_connection_call_finish(conn, res, &error);
827
828         if (error) {
829                 ERROR("create session error %s", error->message);
830                 g_error_free(error);
831         } else
832                 g_variant_unref(result);
833 }
834
835 void obex_transfer_cancel(const char *path)
836 {
837         GDBusConnection *connection = _obex_get_session_dbus();
838
839         DBG("");
840
841         if (!connection)
842                 return;
843
844         if (path == NULL)
845                 return;
846
847         g_dbus_connection_call(connection, "org.bluez.obex",
848                                 path,
849                                 "org.bluez.obex.Transfer1",
850                                 "Cancel",
851                                 NULL,
852                                 NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL,
853                                 simple_cancle_cb, connection);
854 }
855
856 static char *_obex_transfer_get_property_session(const char *path)
857 {
858         char *session = NULL;
859         GDBusProxy *p_proxy;
860
861         DBG("");
862
863         p_proxy = g_dbus_proxy_new_for_bus_sync(
864                                         G_BUS_TYPE_SESSION, 0,
865                                         NULL,
866                                         "org.bluez.obex",
867                                         path,
868                                         PROPERTIES_INTERFACE,
869                                         NULL, NULL);
870
871         if (p_proxy)
872                 session = property_get_string(p_proxy,
873                         OBEX_TRANSFER_INTERFACE, "Session");
874
875         g_object_unref(p_proxy);
876
877         return session;
878 }
879
880 char *obex_transfer_get_property_source(const char *path)
881 {
882         char *source = NULL, *session;
883         GDBusProxy *p_proxy;
884
885         DBG("");
886
887         session = _obex_transfer_get_property_session(path);
888
889         DBG("session = %s", session);
890
891         p_proxy = g_dbus_proxy_new_for_bus_sync(
892                                         G_BUS_TYPE_SESSION, 0,
893                                         NULL,
894                                         "org.bluez.obex",
895                                         session,
896                                         PROPERTIES_INTERFACE,
897                                         NULL, NULL);
898
899         if (p_proxy)
900                 source = property_get_string(p_proxy,
901                         OBEX_SESSION_INTERFACE, "Source");
902
903         g_object_unref(p_proxy);
904
905         return source;
906 }
907
908 char *obex_transfer_get_property_destination(const char *path)
909 {
910         char *dest = NULL, *session;
911         GDBusProxy *p_proxy;
912
913         session = _obex_transfer_get_property_session(path);
914
915         DBG("session = %s, path = %s", session, path);
916
917         p_proxy = g_dbus_proxy_new_for_bus_sync(
918                                         G_BUS_TYPE_SESSION, 0,
919                                         NULL,
920                                         "org.bluez.obex",
921                                         session,
922                                         PROPERTIES_INTERFACE,
923                                         NULL, NULL);
924
925         if (p_proxy)
926                 dest = property_get_string(p_proxy,
927                         OBEX_SESSION_INTERFACE, "Destination");
928
929         g_object_unref(p_proxy);
930
931         return dest;
932 }
933
934 char *obex_transfer_get_property_file_name(const char *path)
935 {
936         char *name = NULL;
937         GDBusProxy *p_proxy;
938
939         p_proxy = g_dbus_proxy_new_for_bus_sync(
940                                         G_BUS_TYPE_SESSION, 0,
941                                         NULL,
942                                         "org.bluez.obex",
943                                         path,
944                                         PROPERTIES_INTERFACE,
945                                         NULL, NULL);
946
947         if (p_proxy)
948                 name = property_get_string(p_proxy,
949                         OBEX_TRANSFER_INTERFACE, "Filename");
950
951         g_object_unref(p_proxy);
952
953         return name;
954 }
955
956 char *obex_transfer_get_property_name(const char *path)
957 {
958         char *name = NULL;
959         GDBusProxy *p_proxy;
960
961         DBG("path = %s", path);
962
963         p_proxy = g_dbus_proxy_new_for_bus_sync(
964                                         G_BUS_TYPE_SESSION, 0,
965                                         NULL,
966                                         "org.bluez.obex",
967                                         path,
968                                         PROPERTIES_INTERFACE,
969                                         NULL, NULL);
970
971         if (p_proxy)
972                 name = property_get_string(p_proxy,
973                         OBEX_TRANSFER_INTERFACE, "Name");
974
975         g_object_unref(p_proxy);
976
977         return name;
978 }