Imported Upstream version 1.0beta3
[platform/upstream/syncevolution.git] / src / dbus / syncevo-server.c
1 /*
2  * Copyright (C) 2009 Intel Corporation
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) version 3.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301  USA
18  */
19
20 #include <glib-object.h>
21 #include <string.h>
22
23 #include "syncevo-server.h"
24 #include "syncevo-marshal.h"
25 #include "syncevo-server-bindings.h"
26
27 typedef struct _ServerAsyncData {
28     SyncevoServer *server;
29     GCallback callback;
30     gpointer userdata;
31 } ServerAsyncData;
32
33 enum {
34     SESSION_CHANGED,
35     PRESENCE_CHANGED,
36     INFO_REQUEST,
37     TEMPLATES_CHANGED,
38     SHUTDOWN,
39     LAST_SIGNAL
40 };
41 static guint32 signals[LAST_SIGNAL] = {0, };
42
43 typedef struct _SyncevoServerPrivate {
44     DBusGProxy *proxy;
45 } SyncevoServerPrivate;
46
47 #define GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SYNCEVO_TYPE_SERVER, SyncevoServerPrivate))
48 G_DEFINE_TYPE (SyncevoServer, syncevo_server, G_TYPE_OBJECT);
49
50 static ServerAsyncData*
51 server_async_data_new (SyncevoServer *server,
52                         GCallback callback,
53                         gpointer userdata)
54 {
55     ServerAsyncData *data;
56
57     data = g_slice_new0 (ServerAsyncData);
58     data->server = server;
59     data->callback = G_CALLBACK (callback);
60     data->userdata = userdata;
61
62     return data;
63 }
64
65 static void
66 server_async_data_free (ServerAsyncData *data)
67 {
68     g_slice_free (ServerAsyncData, data);
69 }
70
71 static void
72 generic_callback (DBusGProxy *proxy,
73                   GError *error,
74                   ServerAsyncData *data)
75 {
76     if (data->callback) {
77         (*(SyncevoServerGenericCb)data->callback) (data->server,
78                                                    error,
79                                                    data->userdata);
80     }
81     server_async_data_free (data);
82 }
83
84 static gboolean
85 generic_error (ServerAsyncData *data)
86 {
87     GError *error;
88
89     error = g_error_new_literal (SYNCEVO_SERVER_ERROR_QUARK,
90                                  SYNCEVO_SERVER_ERROR_NO_DBUS_OBJECT, 
91                                  "The D-Bus object does not exist");
92     (*(SyncevoServerGenericCb)data->callback) (data->server,
93                                                error,
94                                                data->userdata);
95     server_async_data_free (data);
96
97     return FALSE;
98 }
99
100 static void
101 templates_changed_cb (DBusGProxy *proxy,
102                       SyncevoServer *server)
103 {
104     g_signal_emit (server, signals[TEMPLATES_CHANGED], 0);
105 }
106
107 static void
108 session_changed_cb (DBusGProxy *proxy,
109                     char *session_path,
110                     gboolean started,
111                     SyncevoServer *server)
112 {
113     g_signal_emit (server, signals[SESSION_CHANGED], 0, 
114                    session_path, started);
115 }
116
117 static void
118 presence_cb (DBusGProxy *proxy,
119              char *configuration,
120              char *status,
121              char *transport,
122              SyncevoServer *server)
123 {
124     g_signal_emit (server, signals[PRESENCE_CHANGED], 0, 
125                    configuration, status, transport);
126 }
127
128 static void
129 info_request_cb (DBusGProxy *proxy,
130                  char *id,
131                  char *session_path,
132                  char *state,
133                  char *handler_path,
134                  char *type,
135                  GHashTable *parameters,
136                  SyncevoServer *server)
137 {
138     g_signal_emit (server, signals[INFO_REQUEST], 0, 
139                    id, session_path, state, handler_path, type, parameters);
140 }
141
142 static void
143 proxy_destroy_cb (DBusGProxy *proxy, 
144                   SyncevoServer *server)
145 {
146     SyncevoServerPrivate *priv;
147     priv = GET_PRIVATE (server);
148
149     if (priv->proxy) {
150         g_object_unref (priv->proxy);
151     }
152     priv->proxy = NULL;
153
154     g_signal_emit (server, signals[SHUTDOWN], 0);
155 }
156
157 #if 0
158 static void
159 detach_cb (DBusGProxy *proxy,
160            GError *error,
161            gpointer userdata)
162 {
163     if (error) {
164         g_warning ("Server.Detach failed: %s", error->message);
165         g_error_free (error);
166     }
167 }
168 #endif
169
170 static void
171 dispose (GObject *object)
172 {
173     SyncevoServerPrivate *priv;
174
175     priv = GET_PRIVATE (object);
176
177     if (priv->proxy) {
178         dbus_g_proxy_disconnect_signal (priv->proxy, "SessionChanged",
179                                         G_CALLBACK (session_changed_cb),
180                                         object);
181         dbus_g_proxy_disconnect_signal (priv->proxy, "Presence",
182                                         G_CALLBACK (presence_cb),
183                                         object);
184         dbus_g_proxy_disconnect_signal (priv->proxy, "InfoRequest",
185                                         G_CALLBACK (info_request_cb),
186                                         object);
187         dbus_g_proxy_disconnect_signal (priv->proxy, "TemplatesChanged",
188                                         G_CALLBACK (templates_changed_cb),
189                                         object);
190         dbus_g_proxy_disconnect_signal (priv->proxy, "destroy",
191                                         G_CALLBACK (proxy_destroy_cb),
192                                         object);
193         org_syncevolution_Server_detach (priv->proxy, NULL);
194
195         g_object_unref (priv->proxy);
196         priv->proxy = NULL;
197     }
198
199     G_OBJECT_CLASS (syncevo_server_parent_class)->dispose (object);
200 }
201
202 static void
203 attach_cb (DBusGProxy *proxy,
204            GError *error,
205            gpointer userdata)
206 {
207     if (error) {
208         g_warning ("Server.Attach failed: %s", error->message);
209         g_error_free (error);
210     }
211 }
212
213 static gboolean
214 syncevo_server_get_new_proxy (SyncevoServer *server)
215 {
216     DBusGConnection *connection;
217     GError *error;
218     guint32 result;
219     SyncevoServerPrivate *priv;
220     DBusGProxy *proxy;
221
222     priv = GET_PRIVATE (server);
223     error = NULL;
224
225     connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
226     if (connection == NULL) {
227         g_printerr ("Failed to open connection to bus: %s\n",
228                     error->message);
229         g_error_free (error);
230         priv->proxy = NULL;
231         return FALSE;
232     }
233
234     /* we want to use dbus_g_proxy_new_for_name_owner() for the destroy signal
235      * so need to start the service by hand by using DBUS proxy: */
236     proxy = dbus_g_proxy_new_for_name (connection,
237                                        DBUS_SERVICE_DBUS,
238                                        DBUS_PATH_DBUS,
239                                        DBUS_INTERFACE_DBUS);
240     if (!dbus_g_proxy_call (proxy, "StartServiceByName", NULL,
241                             G_TYPE_STRING, DBUS_SERVICE_SYNCEVO_SERVER,
242                             G_TYPE_UINT, 0,
243                             G_TYPE_INVALID,
244                             G_TYPE_UINT, &result,
245                             G_TYPE_INVALID)) {
246         g_warning ("StartServiceByName call failed");
247     }
248     g_object_unref (proxy);
249
250     /* the real proxy */
251     priv->proxy = dbus_g_proxy_new_for_name_owner (connection,
252                                              DBUS_SERVICE_SYNCEVO_SERVER,
253                                              DBUS_PATH_SYNCEVO_SERVER,
254                                              DBUS_INTERFACE_SYNCEVO_SERVER,
255                                              &error);
256     if (priv->proxy == NULL) {
257         g_printerr ("dbus_g_proxy_new_for_name_owner() failed: %s\n", error->message);
258         g_error_free (error);
259         return FALSE;
260     }
261
262     dbus_g_proxy_add_signal (priv->proxy, "SessionChanged",
263                              DBUS_TYPE_G_OBJECT_PATH, G_TYPE_BOOLEAN, G_TYPE_INVALID);
264     dbus_g_proxy_connect_signal (priv->proxy, "SessionChanged",
265                                  G_CALLBACK (session_changed_cb), server, NULL);
266     dbus_g_proxy_add_signal (priv->proxy, "Presence",
267                              G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID);
268     dbus_g_proxy_connect_signal (priv->proxy, "Presence",
269                                  G_CALLBACK (presence_cb), server, NULL);
270     dbus_g_proxy_add_signal (priv->proxy, "InfoRequest",
271                              G_TYPE_STRING,
272                              DBUS_TYPE_G_OBJECT_PATH,
273                              G_TYPE_STRING,
274                              G_TYPE_STRING,
275                              G_TYPE_STRING,
276                              SYNCEVO_TYPE_STRING_STRING_HASHTABLE,
277                              G_TYPE_INVALID);
278     dbus_g_proxy_connect_signal (priv->proxy, "InfoRequest",
279                                  G_CALLBACK (info_request_cb), server, NULL);
280     dbus_g_proxy_add_signal (priv->proxy, "TemplatesChanged", G_TYPE_INVALID);
281     dbus_g_proxy_connect_signal (priv->proxy, "TemplatesChanged",
282                                  G_CALLBACK (templates_changed_cb), server, NULL);
283     g_signal_connect (priv->proxy, "destroy",
284                       G_CALLBACK (proxy_destroy_cb), server);
285
286     org_syncevolution_Server_attach_async (priv->proxy,
287                                            (org_syncevolution_Server_attach_reply)attach_cb,
288                                            NULL);
289
290     return TRUE;
291 }
292
293
294 static void
295 syncevo_server_init (SyncevoServer *server)
296 {
297     SyncevoServerPrivate *priv;
298
299     priv = GET_PRIVATE (server);
300
301     /* SessionChanged */
302     dbus_g_object_register_marshaller (syncevo_marshal_VOID__STRING_BOOLEAN,
303                                        G_TYPE_NONE,
304                                        DBUS_TYPE_G_OBJECT_PATH,
305                                        G_TYPE_BOOLEAN,
306                                        G_TYPE_INVALID);
307     /* Presence */
308     dbus_g_object_register_marshaller (syncevo_marshal_VOID__STRING_STRING_STRING,
309                                        G_TYPE_NONE,
310                                        G_TYPE_STRING,
311                                        G_TYPE_STRING,
312                                        G_TYPE_STRING,
313                                        G_TYPE_INVALID);
314     /* InfoRequest */
315     dbus_g_object_register_marshaller (syncevo_marshal_VOID__STRING_STRING_STRING_STRING_STRING_BOXED,
316                                        G_TYPE_NONE,
317                                        G_TYPE_STRING,
318                                        DBUS_TYPE_G_OBJECT_PATH,
319                                        G_TYPE_STRING,
320                                        G_TYPE_STRING,
321                                        G_TYPE_STRING,
322                                        G_TYPE_BOXED,
323                                        G_TYPE_INVALID);
324
325     /* TemplatesChanged */
326     dbus_g_object_register_marshaller (g_cclosure_marshal_VOID__VOID,
327                                        G_TYPE_NONE,
328                                        G_TYPE_INVALID);
329
330     syncevo_server_get_new_proxy (server);
331 }
332
333 static void
334 syncevo_server_class_init (SyncevoServerClass *klass)
335 {
336     GObjectClass *o_class = (GObjectClass *) klass;
337
338     o_class->dispose = dispose;
339
340     g_type_class_add_private (klass, sizeof (SyncevoServerPrivate));
341
342     signals[SESSION_CHANGED] =
343             g_signal_new ("session-changed",
344                           G_TYPE_FROM_CLASS (klass),
345                           G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE,
346                           G_STRUCT_OFFSET (SyncevoServerClass, session_changed),
347                           NULL, NULL,
348                           syncevo_marshal_VOID__STRING_BOOLEAN,
349                           G_TYPE_NONE,
350                           2, G_TYPE_STRING, G_TYPE_BOOLEAN);
351     signals[PRESENCE_CHANGED] =
352             g_signal_new ("presence-changed",
353                           G_TYPE_FROM_CLASS (klass),
354                           G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE,
355                           G_STRUCT_OFFSET (SyncevoServerClass, presence_changed),
356                           NULL, NULL,
357                           syncevo_marshal_VOID__STRING_STRING_STRING,
358                           G_TYPE_NONE,
359                           3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
360     signals[INFO_REQUEST] =
361             g_signal_new ("info-request",
362                           G_TYPE_FROM_CLASS (klass),
363                           G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE,
364                           G_STRUCT_OFFSET (SyncevoServerClass, info_request),
365                           NULL, NULL,
366                           syncevo_marshal_VOID__STRING_STRING_STRING_STRING_STRING_BOXED,
367                           G_TYPE_NONE,
368                           6, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER);
369     signals[TEMPLATES_CHANGED] =
370             g_signal_new ("templates-changed",
371                           G_TYPE_FROM_CLASS (klass),
372                           G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE,
373                           G_STRUCT_OFFSET (SyncevoServerClass, templates_changed),
374                           NULL, NULL,
375                           g_cclosure_marshal_VOID__VOID,
376                           G_TYPE_NONE,
377                           0);
378     signals[SHUTDOWN] =
379             g_signal_new ("shutdown",
380                           G_TYPE_FROM_CLASS (klass),
381                           G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE,
382                           G_STRUCT_OFFSET (SyncevoServerClass, shutdown),
383                           NULL, NULL,
384                           g_cclosure_marshal_VOID__VOID,
385                           G_TYPE_NONE,
386                           0);
387 }
388
389 SyncevoServer *
390 syncevo_server_get_default ()
391 {
392     static SyncevoServer *server = NULL;
393
394     if (server == NULL) {
395         server = g_object_new (SYNCEVO_TYPE_SERVER, NULL);
396         g_object_add_weak_pointer (G_OBJECT (server),
397                                    (gpointer) &server);
398         return server;
399     }
400
401     return g_object_ref (server);
402 }
403
404
405 static void
406 get_configs_callback (DBusGProxy *proxy, 
407                       char **config_names,
408                       GError *error,
409                       ServerAsyncData *data)
410 {
411     if (data->callback) {
412         (*(SyncevoServerGetConfigsCb)data->callback) (data->server,
413                                                       config_names,
414                                                       error,
415                                                       data->userdata);
416     }
417     server_async_data_free (data);
418 }
419
420 static gboolean
421 get_configs_error (ServerAsyncData *data)
422 {
423     GError *error;
424
425     error = g_error_new_literal (SYNCEVO_SERVER_ERROR_QUARK,
426                                  SYNCEVO_SERVER_ERROR_NO_DBUS_OBJECT, 
427                                  "Could not start service");
428     (*(SyncevoServerGetConfigsCb)data->callback) (data->server,
429                                                   NULL,
430                                                   error,
431                                                   data->userdata);
432     server_async_data_free (data);
433
434     return FALSE;
435 }
436
437 void
438 syncevo_server_get_configs (SyncevoServer *syncevo,
439                             gboolean template,
440                             SyncevoServerGetConfigsCb callback,
441                             gpointer userdata)
442 {
443     ServerAsyncData *data;
444     SyncevoServerPrivate *priv;
445
446     priv = GET_PRIVATE (syncevo);
447
448     data = server_async_data_new (syncevo, G_CALLBACK (callback), userdata);
449
450     if (!priv->proxy && !syncevo_server_get_new_proxy (syncevo)) {
451         if (callback) {
452             g_idle_add ((GSourceFunc)get_configs_error, data);
453         }
454         return;
455     }
456
457     org_syncevolution_Server_get_configs_async
458             (priv->proxy,
459              template,
460              (org_syncevolution_Server_get_configs_reply) get_configs_callback,
461              data);
462 }
463
464 static void
465 get_config_callback (DBusGProxy *proxy,
466                      SyncevoConfig *configuration,
467                      GError *error,
468                      ServerAsyncData *data)
469 {
470     if (data->callback) {
471         (*(SyncevoServerGetConfigCb)data->callback) (data->server,
472                                                      configuration,
473                                                      error,
474                                                      data->userdata);
475     }
476     server_async_data_free (data);
477 }
478
479 static gboolean
480 get_config_error (ServerAsyncData *data)
481 {
482     GError *error;
483
484     error = g_error_new_literal (SYNCEVO_SERVER_ERROR_QUARK,
485                                  SYNCEVO_SERVER_ERROR_NO_DBUS_OBJECT, 
486                                  "Could not start service");
487     (*(SyncevoServerGetConfigCb)data->callback) (data->server,
488                                                  NULL,
489                                                  error,
490                                                  data->userdata);
491     server_async_data_free (data);
492
493     return FALSE;
494 }
495
496 void
497 syncevo_server_get_config (SyncevoServer *syncevo,
498                            const char *config_name, 
499                            gboolean template,
500                            SyncevoServerGetConfigCb callback,
501                            gpointer userdata)
502 {
503     ServerAsyncData *data;
504     SyncevoServerPrivate *priv;
505
506     priv = GET_PRIVATE (syncevo);
507
508     data = server_async_data_new (syncevo, G_CALLBACK (callback), userdata);
509
510     if (!priv->proxy && !syncevo_server_get_new_proxy (syncevo)) {
511         if (callback) {
512             g_idle_add ((GSourceFunc)get_config_error, data);
513         }
514         return;
515     }
516
517     org_syncevolution_Server_get_config_async 
518             (priv->proxy,
519              config_name,
520              template,
521              (org_syncevolution_Server_get_config_reply) get_config_callback,
522              data);
523 }
524
525 static void
526 get_reports_callback (DBusGProxy *proxy,
527                       SyncevoReports *reports,
528                       GError *error,
529                       ServerAsyncData *data)
530 {
531     if (data->callback) {
532         (*(SyncevoServerGetReportsCb)data->callback) (data->server,
533                                                       reports,
534                                                       error,
535                                                       data->userdata);
536     }
537     server_async_data_free (data);
538 }
539
540 static gboolean
541 get_reports_error (ServerAsyncData *data)
542 {
543     GError *error;
544
545     error = g_error_new_literal (SYNCEVO_SERVER_ERROR_QUARK,
546                                  SYNCEVO_SERVER_ERROR_NO_DBUS_OBJECT, 
547                                  "Could not start service");
548     (*(SyncevoServerGetReportsCb)data->callback) (data->server,
549                                                   NULL,
550                                                   error,
551                                                   data->userdata);
552     server_async_data_free (data);
553
554     return FALSE;    
555 }
556
557 void
558 syncevo_server_get_reports (SyncevoServer *syncevo,
559                             const char *config_name,
560                             guint start,
561                             guint count,
562                             SyncevoServerGetReportsCb callback,
563                             gpointer userdata)
564 {
565     ServerAsyncData *data;
566     SyncevoServerPrivate *priv;
567
568     priv = GET_PRIVATE (syncevo);
569
570     data = server_async_data_new (syncevo, G_CALLBACK (callback), userdata);
571
572     if (!priv->proxy && !syncevo_server_get_new_proxy (syncevo)) {
573         if (callback) {
574             g_idle_add ((GSourceFunc)get_reports_error, data);
575         }
576         return;
577     }
578
579     org_syncevolution_Server_get_reports_async
580             (priv->proxy,
581              config_name,
582              start,
583              count,
584              (org_syncevolution_Server_get_reports_reply) get_reports_callback,
585              data);
586 }
587
588 static void
589 start_session_callback (SyncevoServer *syncevo,
590                         char *session_path,
591                         GError *error,
592                         ServerAsyncData *data)
593 {
594     if (data->callback) {
595         (*(SyncevoServerStartSessionCb)data->callback) (data->server,
596                                                         session_path,
597                                                         error,
598                                                         data->userdata);
599     }
600     server_async_data_free (data);
601 }
602
603 static gboolean
604 start_session_error (ServerAsyncData *data)
605 {
606     GError *error;
607
608     error = g_error_new_literal (SYNCEVO_SERVER_ERROR_QUARK,
609                                  SYNCEVO_SERVER_ERROR_NO_DBUS_OBJECT, 
610                                  "Could not start service");
611     (*(SyncevoServerStartSessionCb)data->callback) (data->server,
612                                                     NULL,
613                                                     error,
614                                                     data->userdata);
615     server_async_data_free (data);
616
617     return FALSE;    
618 }
619
620 void
621 syncevo_server_start_session (SyncevoServer *syncevo,
622                               const char *config_name, 
623                               SyncevoServerStartSessionCb callback,
624                               gpointer userdata)
625 {
626     ServerAsyncData *data;
627     SyncevoServerPrivate *priv;
628
629     priv = GET_PRIVATE (syncevo);
630
631     data = server_async_data_new (syncevo, G_CALLBACK (callback), userdata);
632
633     if (!priv->proxy && !syncevo_server_get_new_proxy (syncevo)) {
634         if (callback) {
635             g_idle_add ((GSourceFunc)start_session_error, data);
636         }
637         return;
638     }
639
640     org_syncevolution_Server_start_session_async
641             (priv->proxy,
642              config_name,
643              (org_syncevolution_Server_start_session_reply) start_session_callback,
644              data);
645 }
646
647 static void
648 get_sessions_callback (SyncevoServer *syncevo,
649                        SyncevoSessions *sessions,
650                        GError *error,
651                        ServerAsyncData *data)
652 {
653     if (data->callback) {
654         (*(SyncevoServerGetSessionsCb)data->callback) (data->server,
655                                                        sessions,
656                                                        error,
657                                                        data->userdata);
658     }
659     server_async_data_free (data);
660 }
661
662 static gboolean
663 get_sessions_error (ServerAsyncData *data)
664 {
665     GError *error;
666
667     error = g_error_new_literal (SYNCEVO_SERVER_ERROR_QUARK,
668                                  SYNCEVO_SERVER_ERROR_NO_DBUS_OBJECT, 
669                                  "Could not start service");
670     (*(SyncevoServerGetSessionsCb)data->callback) (data->server,
671                                                    NULL,
672                                                    error,
673                                                    data->userdata);
674     server_async_data_free (data);
675
676     return FALSE;    
677 }
678
679 void
680 syncevo_server_get_sessions (SyncevoServer *syncevo,
681                              SyncevoServerGetSessionsCb callback,
682                              gpointer userdata)
683 {
684     ServerAsyncData *data;
685     SyncevoServerPrivate *priv;
686
687     priv = GET_PRIVATE (syncevo);
688
689     data = server_async_data_new (syncevo, G_CALLBACK (callback), userdata);
690
691     if (!priv->proxy && !syncevo_server_get_new_proxy (syncevo)) {
692         if (callback) {
693             g_idle_add ((GSourceFunc)get_sessions_error, data);
694         }
695         return;
696     }
697
698     org_syncevolution_Server_get_sessions_async
699             (priv->proxy,
700              (org_syncevolution_Server_get_reports_reply) get_sessions_callback,
701              data);
702 }
703
704
705 static void
706 check_presence_callback (SyncevoServer *syncevo,
707                          char *status,
708                          char *transport,
709                          GError *error,
710                          ServerAsyncData *data)
711 {
712     if (data->callback) {
713         (*(SyncevoServerGetPresenceCb)data->callback) (data->server,
714                                                        status,
715                                                        transport,
716                                                        error,
717                                                        data->userdata);
718     }
719     server_async_data_free (data);
720 }
721
722 static gboolean
723 check_presence_error (ServerAsyncData *data)
724 {
725     GError *error;
726
727     error = g_error_new_literal (SYNCEVO_SERVER_ERROR_QUARK,
728                                  SYNCEVO_SERVER_ERROR_NO_DBUS_OBJECT, 
729                                  "Could not start service");
730     (*(SyncevoServerGetPresenceCb)data->callback) (data->server,
731                                                    NULL,
732                                                    NULL,
733                                                    error,
734                                                    data->userdata);
735     server_async_data_free (data);
736
737     return FALSE;
738 }
739
740
741 void
742 syncevo_server_get_presence (SyncevoServer *syncevo,
743                              const char *config_name,
744                              SyncevoServerGetPresenceCb callback,
745                              gpointer userdata)
746 {
747     ServerAsyncData *data;
748     SyncevoServerPrivate *priv;
749
750     priv = GET_PRIVATE (syncevo);
751
752     data = server_async_data_new (syncevo, G_CALLBACK (callback), userdata);
753
754     if (!priv->proxy && !syncevo_server_get_new_proxy (syncevo)) {
755         if (callback) {
756             g_idle_add ((GSourceFunc)check_presence_error, data);
757         }
758         return;
759     }
760
761     org_syncevolution_Server_check_presence_async
762             (priv->proxy,
763              config_name,
764              (org_syncevolution_Server_check_presence_reply) check_presence_callback,
765              data);
766 }
767
768 void syncevo_server_check_source (SyncevoServer *server,
769                                   const char *config,
770                                   const char *source,
771                                   SyncevoServerGenericCb callback,
772                                   gpointer userdata)
773 {
774     ServerAsyncData *data;
775     SyncevoServerPrivate *priv;
776
777     priv = GET_PRIVATE (server);
778
779     data = server_async_data_new (server, G_CALLBACK (callback), userdata);
780
781     if (!priv->proxy) {
782         if (callback) {
783             g_idle_add ((GSourceFunc)generic_error, data);
784         }
785         return;
786     }
787
788     org_syncevolution_Server_check_source_async 
789             (priv->proxy,
790              config,
791              source,
792              (org_syncevolution_Server_check_source_reply) generic_callback,
793              data);
794 }
795
796 void
797 syncevo_server_info_response (SyncevoServer *server,
798                               const char *id,
799                               const char *state,
800                               GHashTable *response,
801                               SyncevoServerGenericCb callback,
802                               gpointer userdata)
803 {
804     ServerAsyncData *data;
805     SyncevoServerPrivate *priv;
806
807     priv = GET_PRIVATE (server);
808
809     data = server_async_data_new (server, G_CALLBACK (callback), userdata);
810
811     if (!priv->proxy) {
812         if (callback) {
813             g_idle_add ((GSourceFunc)generic_error, data);
814         }
815         return;
816     }
817
818     org_syncevolution_Server_info_response_async
819             (priv->proxy,
820              id,
821              state,
822              response,
823              (org_syncevolution_Server_info_response_reply) generic_callback,
824              data);
825 }