upgrade obexd to 0.47
[profile/ivi/obexd.git] / plugins / messages-tizen.c
1 /*
2  *
3  *  OBEX Server
4  *
5  *  Copyright (C) 2009-2010  Intel Corporation
6  *  Copyright (C) 2007-2010  Marcel Holtmann <marcel@holtmann.org>
7  *
8  *
9  *  This program is free software; you can redistribute it and/or modify
10  *  it under the terms of the GNU General Public License as published by
11  *  the Free Software Foundation; either version 2 of the License, or
12  *  (at your option) any later version.
13  *
14  *  This program is distributed in the hope that it will be useful,
15  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  *  GNU General Public License for more details.
18  *
19  *  You should have received a copy of the GNU General Public License
20  *  along with this program; if not, write to the Free Software
21  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
22  *
23  */
24
25 #ifdef HAVE_CONFIG_H
26 #include <config.h>
27 #endif
28
29 #include <errno.h>
30 #include <glib.h>
31 #include <string.h>
32 #include "log.h"
33 #include<messages.h>
34
35 #include <dbus/dbus.h>
36
37 #define QUERY_GET_FOLDER_TREE "GetFolderTree"
38 #define QUERY_GET_MSG_LIST "GetMessageList"
39 #define QUERY_GET_MESSAGE "GetMessage"
40 #define QUERY_UPDATE_MESSAGE "UpdateMessage"
41 #define QUERY_MESSAGE_STATUS "MessageStatus"
42 #define QUERY_NOTI_REGISTRATION "NotiRegistration"
43
44 #define BT_MAP_SERVICE_OBJECT_PATH "/org/bluez/map_agent"
45 #define BT_MAP_SERVICE_NAME "org.bluez.map_agent"
46 #define BT_MAP_SERVICE_INTERFACE "org.bluez.MapAgent"
47
48 static DBusConnection *g_conn = NULL;
49
50 struct mns_reg_data {
51         int notification_status;
52         char *remote_addr;
53 };
54
55 struct message_folder {
56         char *name;
57         GSList *subfolders;
58 };
59
60 struct session {
61         char *cwd;
62         struct message_folder *folder;
63         char *name;
64         uint16_t max;
65         uint16_t offset;
66         void *user_data;
67         void (*folder_list_cb)(void *session, int err, uint16_t size,
68                                         const char *name, void *user_data);
69         struct messages_message *msg;
70         const struct messages_filter *filter;
71         void (*msg_list_cb)(void *session, int err, int size, gboolean newmsg,
72                                 const struct messages_message *entry,
73                                 void *user_data);
74         void (*get_msg_cb)(void *session, int err, gboolean fmore,
75                                 const char *chunk, void *user_data);
76         void (*msg_update_cb)(void *session, int err, void *user_data);
77         void (*msg_status_cb)(void *session, int err, void *user_data);
78 };
79
80 static struct message_folder *folder_tree = NULL;
81
82 static struct message_folder *get_folder(const char *folder)
83 {
84         GSList *folders = folder_tree->subfolders;
85         struct message_folder *last = NULL;
86         char **path;
87         int i;
88
89         if (g_strcmp0(folder, "/") == 0)
90                 return folder_tree;
91
92         path = g_strsplit(folder, "/", 0);
93
94         for (i = 1; path[i] != NULL; i++) {
95                 gboolean match_found = FALSE;
96                 GSList *l;
97
98                 for (l = folders; l != NULL; l = g_slist_next(l)) {
99                         struct message_folder *folder = l->data;
100
101                         if (g_ascii_strncasecmp(folder->name, path[i],
102                                         strlen(folder->name)) == 0) {
103                                 match_found = TRUE;
104                                 last = l->data;
105                                 folders = folder->subfolders;
106                                 break;
107                         }
108                 }
109
110                 if (!match_found) {
111                         g_strfreev(path);
112                         return NULL;
113                 }
114         }
115
116         g_strfreev(path);
117
118         return last;
119 }
120
121 static void destroy_folder_tree(void *root)
122 {
123         struct message_folder *folder = root;
124         GSList *tmp, *next;
125
126         if (folder == NULL)
127                 return;
128
129         g_free(folder->name);
130
131         tmp = folder->subfolders;
132         while (tmp != NULL) {
133                 next = g_slist_next(tmp);
134                 destroy_folder_tree(tmp->data);
135                 tmp = next;
136         }
137         g_slist_free(folder->subfolders);
138         g_free(folder);
139 }
140
141 static struct message_folder *create_folder(const char *name)
142 {
143         struct message_folder *folder = g_new0(struct message_folder, 1);
144
145         folder->name = g_strdup(name);
146         return folder;
147 }
148
149 static void create_folder_tree()
150 {
151
152         struct message_folder *parent, *child;
153
154         folder_tree = create_folder("/");
155
156         parent = create_folder("telecom");
157         folder_tree->subfolders = g_slist_append(folder_tree->subfolders,
158                                                                 parent);
159
160         child = create_folder("msg");
161         parent->subfolders = g_slist_append(parent->subfolders, child);
162 }
163
164 int messages_init(void)
165 {
166         g_conn = dbus_bus_get(DBUS_BUS_SESSION, NULL);
167         if (!g_conn) {
168                 error("Can't get on session bus");
169                 return -1;
170         }
171
172         create_folder_tree();
173         return 0;
174 }
175
176 void messages_exit(void)
177 {
178         destroy_folder_tree(folder_tree);
179
180         if (g_conn) {
181                 dbus_connection_unref(g_conn);
182                 g_conn = NULL;
183         }
184 }
185
186 static void message_get_folder_list(DBusPendingCall *call, void *user_data)
187 {
188         DBusMessage *reply = dbus_pending_call_steal_reply(call);
189         DBusMessageIter iter;
190         DBusMessageIter iter_struct;
191         DBusMessageIter entry;
192         DBusError derr;
193         const char *name = NULL;
194         struct message_folder *parent = {0,}, *child = {0,};
195         GSList *l;
196
197         DBG("+\n");
198
199         for (l = folder_tree->subfolders; l != NULL; l = parent->subfolders)
200                 parent = l->data;
201
202         DBG("Last child folder = %s \n", parent->name);
203         dbus_error_init(&derr);
204
205         if (dbus_set_error_from_message(&derr, reply)) {
206                 error("Replied with an error: %s, %s", derr.name, derr.message);
207                 dbus_error_free(&derr);
208         } else {
209                 dbus_message_iter_init(reply, &iter);
210                 dbus_message_iter_recurse(&iter, &iter_struct);
211
212                 while (dbus_message_iter_get_arg_type(&iter_struct) ==
213                                                         DBUS_TYPE_STRUCT) {
214                         dbus_message_iter_recurse(&iter_struct, &entry);
215
216                         dbus_message_iter_get_basic(&entry, &name);
217                         DBG("Folder name = %s \n", name);
218                         child = create_folder(name);
219                         parent->subfolders = g_slist_append(parent->subfolders,
220                                                         child);
221                         dbus_message_iter_next(&iter_struct);
222                 }
223         }
224         dbus_message_unref(reply);
225         DBG("-\n");
226 }
227
228 static void message_get_msg_list(DBusPendingCall *call, void *user_data)
229 {
230         DBusMessage *reply = dbus_pending_call_steal_reply(call);
231         DBusMessageIter iter;
232         DBusMessageIter iter_struct;
233         DBusMessageIter entry;
234         DBusError derr;
235         const char *msg_handle;
236         const char *msg_type;
237         const char *msg_time;
238         struct session *session = user_data;
239         struct messages_message *data = g_new0(struct messages_message, 1);
240
241         DBG("+\n");
242
243         dbus_error_init(&derr);
244
245         if (dbus_set_error_from_message(&derr, reply)) {
246                 error("Replied with an error: %s, %s", derr.name, derr.message);
247                 dbus_error_free(&derr);
248         } else {
249                 dbus_message_iter_init(reply, &iter);
250                 dbus_message_iter_recurse(&iter, &iter_struct);
251
252                 while (dbus_message_iter_get_arg_type(&iter_struct) ==
253                                                         DBUS_TYPE_STRUCT) {
254                         dbus_message_iter_recurse(&iter_struct, &entry);
255                         dbus_message_iter_get_basic(&entry, &msg_handle);
256                         DBG("Msg handle = %s \n", msg_handle);
257                         data->handle = g_strdup(msg_handle);
258                         dbus_message_iter_next(&entry);
259                         dbus_message_iter_get_basic(&entry, &msg_type);
260                         DBG("Msg Type = %s \n", msg_type);
261                         data->mask |= PMASK_TYPE;
262                         data->type = g_strdup(msg_type);
263                         dbus_message_iter_next(&entry);
264                         dbus_message_iter_get_basic(&entry, &msg_time);
265                         DBG("Msg date & time = %s \n", msg_time);
266                         data->mask |= PMASK_DATETIME;
267                         data->datetime = g_strdup(msg_time);
268
269                         session->msg_list_cb(session, -EAGAIN, 1,
270                                         TRUE,
271                                         data,
272                                         session->user_data);
273                         dbus_message_iter_next(&iter_struct);
274                 }
275                 session->msg_list_cb(session, 0, 0,
276                                         FALSE,
277                                         NULL,
278                                         session->user_data);
279         }
280         dbus_message_unref(reply);
281         DBG("-\n");
282 }
283
284 static void message_get_msg(DBusPendingCall *call, void *user_data)
285 {
286         DBusMessage *reply = dbus_pending_call_steal_reply(call);
287         DBusMessageIter iter;
288         DBusMessageIter iter_struct;
289         DBusMessageIter entry;
290         DBusError derr;
291         struct session *session = user_data;
292         char *msg_body;
293
294         DBG("+\n");
295
296         dbus_error_init(&derr);
297         if (dbus_set_error_from_message(&derr, reply)) {
298                 error("Replied with an error: %s, %s", derr.name, derr.message);
299                 dbus_error_free(&derr);
300         } else {
301                 dbus_message_iter_init(reply, &iter);
302                 dbus_message_iter_recurse(&iter, &iter_struct);
303
304                 if (dbus_message_iter_get_arg_type(&iter_struct) ==
305                                                         DBUS_TYPE_STRUCT) {
306                         dbus_message_iter_recurse(&iter_struct, &entry);
307                         dbus_message_iter_get_basic(&entry, &msg_body);
308                         DBG("Msg handle = %s \n", msg_body);
309                 }
310                 session->get_msg_cb(session, -EAGAIN, FALSE,
311                                         msg_body, session->user_data);
312                 session->get_msg_cb(session, 0, FALSE,
313                                         NULL, session->user_data);
314         }
315         dbus_message_unref(reply);
316         DBG("-\n");
317 }
318
319 int messages_connect(void **s)
320 {
321         DBusPendingCall *call;
322         DBusMessage *message;
323         DBG("+\n");
324
325         struct session *session = g_new0(struct session, 1);
326
327         session->cwd = g_strdup("/");
328         session->folder = folder_tree;
329
330         *s = session;
331
332         message = dbus_message_new_method_call(BT_MAP_SERVICE_NAME,
333                                                 BT_MAP_SERVICE_OBJECT_PATH,
334                                                 BT_MAP_SERVICE_INTERFACE,
335                                                 QUERY_GET_FOLDER_TREE);
336         if (!message) {
337                 error("Can't allocate new message");
338                 return -1;
339         }
340
341         if (dbus_connection_send_with_reply(g_conn, message, &call, -1) ==
342                         FALSE) {
343                 error("Could not send dbus message");
344                 dbus_message_unref(message);
345                 return -1;
346         }
347
348         dbus_pending_call_set_notify(call, message_get_folder_list, session,
349                                                 NULL);
350         dbus_message_unref(message);
351         DBG("-\n");
352         return 0;
353 }
354
355 void messages_disconnect(void *s)
356 {
357         DBG("+\n");
358         struct session *session = s;
359
360         g_free(session->cwd);
361         g_free(session);
362
363         DBG("-\n");
364 }
365
366 int messages_set_notification_registration(void *session,
367                 void (*send_event)(void *session,
368                         const struct messages_event *event, void *user_data),
369                 void *user_data)
370 {
371         return -EINVAL;
372 }
373
374 int messages_set_folder(void *s, const char *name, gboolean cdup)
375 {
376         struct session *session = s;
377         char *newrel = NULL;
378         char *newabs;
379         char *tmp;
380
381         if (name && (strchr(name, '/') || strcmp(name, "..") == 0))
382                 return -EBADR;
383
384         if (cdup) {
385                 if (session->cwd[0] == 0)
386                         return -ENOENT;
387
388                 newrel = g_path_get_dirname(session->cwd);
389
390                 /* We use empty string for indication of the root directory */
391                 if (newrel[0] == '.' && newrel[1] == 0)
392                         newrel[0] = 0;
393         }
394
395         tmp = newrel;
396         if (!cdup && (!name || name[0] == 0))
397                 newrel = g_strdup("");
398         else
399                 newrel = g_build_filename(newrel ? newrel : session->cwd, name,
400                                                                         NULL);
401         g_free(tmp);
402
403         if (newrel[0] != '/')
404                 newabs = g_build_filename("/", newrel, NULL);
405         else
406                 newabs = g_strdup(newrel);
407
408         session->folder = get_folder(newabs);
409         if (session->folder == NULL) {
410                 g_free(newrel);
411                 g_free(newabs);
412
413                 return -ENOENT;
414         }
415
416         g_free(newrel);
417         g_free(session->cwd);
418         session->cwd = newabs;
419
420         return 0;
421 }
422
423 static gboolean async_get_folder_listing(void *s)
424 {
425         struct session *session = s;
426         gboolean count = FALSE;
427         int folder_count = 0;
428         char *path = NULL;
429         struct message_folder *folder;
430         GSList *dir;
431
432         if (session->name && strchr(session->name, '/') != NULL)
433                 goto done;
434
435         path = g_build_filename(session->cwd, session->name, NULL);
436
437         if (path == NULL || strlen(path) == 0)
438                 goto done;
439
440         folder = get_folder(path);
441
442         if (folder == NULL)
443                 goto done;
444
445         if (session->max == 0) {
446                 session->max = 0xffff;
447                 session->offset = 0;
448                 count = TRUE;
449         }
450
451         for (dir = folder->subfolders; dir &&
452                                 (folder_count - session->offset) < session->max;
453                                 folder_count++, dir = g_slist_next(dir)) {
454                 struct message_folder *dir_data = dir->data;
455
456                 if (count == FALSE && session->offset <= folder_count)
457                         session->folder_list_cb(session, -EAGAIN, 0,
458                                         dir_data->name, session->user_data);
459         }
460
461  done:
462         session->folder_list_cb(session, 0, folder_count, NULL,
463                                                         session->user_data);
464
465         g_free(path);
466         g_free(session->name);
467
468         return FALSE;
469 }
470
471 int messages_get_folder_listing(void *s, const char *name,
472                                         uint16_t max, uint16_t offset,
473                                         messages_folder_listing_cb callback,
474                                         void *user_data)
475 {
476         DBG("+\n");
477         struct session *session = s;
478         session->name = g_strdup(name);
479         session->max = max;
480         session->offset = offset;
481         session->folder_list_cb = callback;
482         session->user_data = user_data;
483
484         g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, async_get_folder_listing,
485                                                 session, NULL);
486
487         DBG("-\n");
488         return 0;
489 }
490
491 int messages_get_messages_listing(void *session, const char *name,
492                                 uint16_t max, uint16_t offset, uint8_t subject_len,
493                                 const struct messages_filter *filter,
494                                 messages_get_messages_listing_cb callback,
495                                 void *user_data)
496 {
497         DBusPendingCall *call;
498         DBusMessage *message;
499         struct session *s = session;
500
501         if (strlen(name) != 0)
502                 s->name = g_strdup(name);
503          else
504                 s->name = g_strdup(s->cwd);
505
506         s->max = max;
507         s->offset = offset;
508         s->filter = filter;
509         s->msg_list_cb = (void *)callback;
510         s->user_data = user_data;
511
512         message = dbus_message_new_method_call(BT_MAP_SERVICE_NAME,
513                                                 BT_MAP_SERVICE_OBJECT_PATH,
514                                                 BT_MAP_SERVICE_INTERFACE,
515                                                 QUERY_GET_MSG_LIST);
516         if (!message) {
517                 error("Can't allocate new message");
518                 g_free(s->name);
519                 return -1;
520         }
521         dbus_message_append_args(message, DBUS_TYPE_STRING, &s->name,
522                                                         DBUS_TYPE_INVALID);
523
524         if (dbus_connection_send_with_reply(g_conn, message, &call, -1) ==
525                                         FALSE) {
526                 error("Could not send dbus message");
527                 dbus_message_unref(message);
528                 g_free(s->name);
529                 return -1;
530         }
531         dbus_pending_call_set_notify(call, message_get_msg_list, s, NULL);
532         dbus_message_unref(message);
533         g_free(s->name);
534         DBG("-\n");
535         return 1;
536 }
537
538 int messages_get_message(void *session,
539                                         const char *handle,
540                                         unsigned long flags,
541                                         messages_get_message_cb callback,
542                                         void *user_data)
543 {
544         DBusPendingCall *call;
545         DBusMessage *message;
546         struct session *s = session;
547         char *message_name;
548         DBG("+\n");
549
550         if (NULL != handle) {
551                 message_name =  g_strdup(handle);
552                 DBG("Message handle = %s\n", handle);
553         } else {
554                 return -1;
555         }
556         s->get_msg_cb = callback;
557         s->user_data = user_data;
558
559         message = dbus_message_new_method_call(BT_MAP_SERVICE_NAME,
560                                                 BT_MAP_SERVICE_OBJECT_PATH,
561                                                 BT_MAP_SERVICE_INTERFACE,
562                                                 QUERY_GET_MESSAGE);
563         if (!message) {
564                 error("Can't allocate new message");
565                 g_free(message_name);
566                 return -1;
567         }
568         dbus_message_append_args(message, DBUS_TYPE_STRING, &message_name,
569                                                         DBUS_TYPE_INVALID);
570
571         if (dbus_connection_send_with_reply(g_conn, message, &call, -1) ==
572                                         FALSE) {
573                 error("Could not send dbus message");
574                 dbus_message_unref(message);
575                 g_free(message_name);
576                 return -1;
577         }
578         dbus_pending_call_set_notify(call, message_get_msg, s, NULL);
579         dbus_message_unref(message);
580         g_free(message_name);
581         DBG("-\n");
582         return 1;
583 }
584
585 static void message_update_msg(DBusPendingCall *call, void *user_data)
586 {
587         DBusMessage *reply = dbus_pending_call_steal_reply(call);
588         DBusMessageIter iter;
589         DBusError derr;
590         struct session *session = user_data;
591         int err;
592         DBG("+\n");
593
594         dbus_error_init(&derr);
595         if (dbus_set_error_from_message(&derr, reply)) {
596                 error("Replied with an error: %s, %s", derr.name, derr.message);
597                 dbus_error_free(&derr);
598         } else {
599                 dbus_message_iter_init(reply, &iter);
600                 if (dbus_message_iter_get_arg_type(&iter) ==
601                                                         DBUS_TYPE_INT32) {
602                         dbus_message_iter_get_basic(&iter, &err);
603                         DBG("Error : %d\n", err);
604                         session->msg_update_cb(session, err,
605                                                 session->user_data);
606                 }
607         }
608         dbus_message_unref(reply);
609         DBG("-\n");
610 }
611
612 int messages_update_inbox(void *session,
613                                         messages_update_inbox_cb callback,
614                                         void *user_data)
615 {
616         DBusPendingCall *call;
617         DBusMessage *message;
618         struct session *s = session;
619
620         DBG("+\n");
621
622         s->msg_update_cb = callback;
623         s->user_data = user_data;
624
625         message = dbus_message_new_method_call(BT_MAP_SERVICE_NAME,
626                                                 BT_MAP_SERVICE_OBJECT_PATH,
627                                                 BT_MAP_SERVICE_INTERFACE,
628                                                 QUERY_UPDATE_MESSAGE);
629         if (!message) {
630                 error("Can't allocate new message");
631                 return -1;
632         }
633
634         if (dbus_connection_send_with_reply(g_conn, message, &call, -1) ==
635                                         FALSE) {
636                 error("Could not send dbus message");
637                 dbus_message_unref(message);
638                 return -1;
639         }
640         dbus_pending_call_set_notify(call, message_update_msg, s, NULL);
641         dbus_message_unref(message);
642         DBG("-\n");
643         return 1;
644 }
645
646 static void message_status_msg(DBusPendingCall *call, void *user_data)
647 {
648         DBusMessage *reply = dbus_pending_call_steal_reply(call);
649         DBusMessageIter iter;
650         DBusError derr;
651         struct session *session = user_data;
652         int err;
653
654         DBG("+\n");
655
656         dbus_error_init(&derr);
657         if (dbus_set_error_from_message(&derr, reply)) {
658                 error("Replied with an error: %s, %s", derr.name, derr.message);
659                 dbus_error_free(&derr);
660         } else {
661                 dbus_message_iter_init(reply, &iter);
662                 if (dbus_message_iter_get_arg_type(&iter) ==
663                                                         DBUS_TYPE_INT32) {
664                         dbus_message_iter_get_basic(&iter, &err);
665                         DBG("Error : %d\n", err);
666                         session->msg_status_cb(session, err,
667                                                 session->user_data);
668                 }
669         }
670         dbus_message_unref(reply);
671         DBG("-\n");
672 }
673
674 int messages_set_message_status(void *session, const char *handle,
675                                         int indicator, int value,
676                                         messages_set_message_status_cb callback,
677                                         void *user_data)
678 {
679         DBusPendingCall *call;
680         DBusMessage *message;
681         struct session *s = session;
682         char *message_name;
683
684         DBG("+\n");
685
686         if (NULL != handle) {
687                 message_name =  g_strdup(handle);
688                 DBG("Message handle = %s\n", handle);
689         } else {
690                 return -1;
691         }
692
693         s->msg_status_cb = callback;
694         s->user_data = user_data;
695
696         message = dbus_message_new_method_call(BT_MAP_SERVICE_NAME,
697                                                 BT_MAP_SERVICE_OBJECT_PATH,
698                                                 BT_MAP_SERVICE_INTERFACE,
699                                                 QUERY_MESSAGE_STATUS);
700         if (!message) {
701                 error("Can't allocate new message");
702                 g_free(message_name);
703                 return -1;
704         }
705
706         dbus_message_append_args(message, DBUS_TYPE_STRING, &message_name,
707                                                 DBUS_TYPE_INT32, &indicator,
708                                                 DBUS_TYPE_INT32, &value,
709                                                 DBUS_TYPE_INVALID);
710
711         if (dbus_connection_send_with_reply(g_conn, message, &call, -1) ==
712                                         FALSE) {
713                 error("Could not send dbus message");
714                 g_free(message_name);
715                 dbus_message_unref(message);
716                 return -1;
717         }
718         dbus_pending_call_set_notify(call, message_status_msg, s, NULL);
719         dbus_message_unref(message);
720         g_free(message_name);
721         DBG("-\n");
722         return 1;
723 }
724
725 static gboolean notification_registration(gpointer user_data)
726 {
727         DBG("+\n");
728         DBusMessage *message = NULL;
729         gboolean reg;
730         struct mns_reg_data *data = (struct mns_reg_data *)user_data;
731
732         message = dbus_message_new_method_call(BT_MAP_SERVICE_NAME,
733                                         BT_MAP_SERVICE_OBJECT_PATH,
734                                         BT_MAP_SERVICE_INTERFACE,
735                                         QUERY_NOTI_REGISTRATION);
736         if (!message) {
737                 error("Can't allocate new message");
738                 goto done;
739         }
740
741         DBG("data->notification_status = %d\n", data->notification_status);
742
743         if (data->notification_status == 1)
744                 reg = TRUE;
745         else
746                 reg = FALSE;
747
748         dbus_message_append_args(message, DBUS_TYPE_STRING, &data->remote_addr,
749                                                 DBUS_TYPE_BOOLEAN, &reg,
750                                                 DBUS_TYPE_INVALID);
751
752         if (dbus_connection_send(g_conn, message, NULL) == FALSE)
753                 error("Could not send dbus message");
754
755 done:
756         if (message)
757                 dbus_message_unref(message);
758
759         g_free(data->remote_addr);
760         g_free(data);
761
762         DBG("-\n");
763         return FALSE;
764 }
765
766 int messages_notification_registration(void *session,
767                                 char *address, int status,
768                                 messages_notification_registration_cb callback,
769                                 void *user_data)
770 {
771         DBG("+\n");
772         struct mns_reg_data *data = g_new0(struct mns_reg_data, 1);
773         data->notification_status = status;
774         data->remote_addr = g_strdup(address);
775
776         DBG("status = %d\n", status);
777
778         g_idle_add(notification_registration, data);
779         DBG("-\n");
780         return 1;
781 }
782
783 void messages_abort(void *session)
784 {
785 }
786