5 * Copyright (c) 2000-2016 Samsung Electronics Co., Ltd. All rights reserved.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
35 #include <dbus/dbus.h>
37 #define QUERY_GET_FOLDER_TREE "GetFolderTree"
38 #define QUERY_GET_MSG_LIST "GetMessageList"
39 #define QUERY_GET_MESSAGE "GetMessage"
40 #define QUERY_PUSH_MESSAGE "PushMessage"
41 #define QUERY_PUSH_MESSAGE_DATA "PushMessageData"
42 #define QUERY_UPDATE_MESSAGE "UpdateMessage"
43 #define QUERY_SET_READ_STATUS "SetReadStatus"
44 #define QUERY_SET_DELETE_STATUS "SetDeleteStatus"
45 #define QUERY_NOTI_REGISTRATION "NotiRegistration"
46 #define QUERY_DESTROY_AGENT "DestroyAgent"
48 #define BT_MAP_SERVICE_OBJECT_PATH "/org/bluez/map_agent"
49 #define BT_MAP_SERVICE_NAME "org.bluez.map_agent"
50 #define BT_MAP_SERVICE_INTERFACE "org.bluez.MapAgent"
52 /* Added as per MAP specification */
53 #define BT_MAP_LIST_ITEM_MAX_LEN 256
55 static DBusConnection *g_conn = NULL;
58 uint8_t notification_status;
62 struct message_folder {
69 struct message_folder *folder;
74 struct messages_filter *filter;
75 struct messages_message *msg;
76 void (*folder_list_cb)(void *session, int err, uint16_t size,
77 const char *name, void *user_data);
78 void (*msg_list_cb)(void *session, int err, int size, gboolean newmsg,
79 const struct messages_message *entry,
81 void (*push_msg_cb)(void *session, int err, guint64 handle,
83 void (*get_msg_cb)(void *session, int err, gboolean fmore,
84 const char *chunk, void *user_data);
85 void (*msg_update_cb)(void *session, int err, void *user_data);
86 void (*msg_status_cb)(void *session, int err, void *user_data);
89 static struct message_folder *folder_tree = NULL;
91 static void message_list_item_free(struct messages_message *data)
97 g_free(data->subject);
100 g_free(data->datetime);
101 data->datetime = NULL;
103 g_free(data->sender_name);
104 data->sender_name = NULL;
106 g_free(data->sender_addressing);
107 data->sender_addressing = NULL;
109 g_free(data->replyto_addressing);
110 data->replyto_addressing = NULL;
112 g_free(data->recipient_name);
113 data->recipient_name = NULL;
115 g_free(data->recipient_addressing);
116 data->recipient_addressing = NULL;
121 g_free(data->reception_status);
122 data->reception_status = NULL;
127 g_free(data->attachment_size);
128 data->attachment_size = NULL;
132 static void session_filter_free(struct messages_filter *data)
138 g_free((gpointer)data->period_begin);
139 g_free((gpointer)data->period_end);
140 g_free((gpointer)data->recipient);
141 g_free((gpointer)data->originator);
146 static gboolean is_time_in_period(char *ref_time, char *period)
148 guint64 ref_date_val;
151 guint64 ref_time_val;
159 start = strtok_r(ref_time, "T", &end);
160 if (NULL == start || NULL == end)
163 snprintf(temp, sizeof(temp), "%s", start);
164 ref_date_val = g_ascii_strtoull(temp, NULL, 16);
165 snprintf(temp, sizeof(temp), "%s", end);
166 ref_time_val = g_ascii_strtoull(temp, NULL, 16);
168 start = strtok_r(period, "T", &end);
169 if (NULL == start || NULL == end)
172 snprintf(temp, sizeof(temp), "%s", start);
173 date_val = g_ascii_strtoull(temp, NULL, 16);
174 snprintf(temp, sizeof(temp), "%s", end);
175 time_val = g_ascii_strtoull(temp, NULL, 16);
177 if (ref_date_val < date_val) {
179 } else if (ref_date_val > date_val) {
182 if (ref_time_val <= time_val)
189 static gboolean __filter_timebased(char *begin, char *end, char *time)
193 if (!begin && !end) {
194 /* If start and stop are not specified
198 } else if (!end && begin) {
199 /* If "FilterPeriodEnd" is not specified the returned
200 message listing shall include the messages from
201 "FilterPeriodBegin" to current time */
203 return is_time_in_period(begin, time);
204 } else if (!begin && end) {
205 /* If "FilterPeriodBegin" is not specified the returned
206 message listing shall include the messages older than
209 return is_time_in_period(time, end);
212 if (TRUE == is_time_in_period(end, begin))
215 ret = is_time_in_period(begin, time);
217 return is_time_in_period(time, end);
223 static uint8_t get_type_val(const char *type)
225 if (!g_strcmp0(type, "SMS_GSM"))
227 else if (!g_strcmp0(type, "SMS_CDMA"))
229 else if (!g_strcmp0(type, "EMAIL"))
231 else if (!g_strcmp0(type, "MMS"))
237 static uint8_t get_read_status_val(gboolean read)
240 return 0x02; /* Read messages */
242 return 0x01; /* Unread messages */
245 static uint8_t get_priority_val(gboolean priority)
248 return 0x01; /* High priority */
250 return 0x02; /* Low priority */
253 static struct message_folder *get_folder(const char *folder)
255 GSList *folders = folder_tree->subfolders;
256 struct message_folder *last = NULL;
260 if (g_strcmp0(folder, "/") == 0)
263 path = g_strsplit(folder, "/", 0);
265 for (i = 1; path[i] != NULL; i++) {
266 gboolean match_found = FALSE;
269 for (l = folders; l != NULL; l = g_slist_next(l)) {
270 struct message_folder *folder = l->data;
272 if (g_ascii_strncasecmp(folder->name, path[i],
273 strlen(folder->name)) == 0) {
276 folders = folder->subfolders;
292 static void destroy_folder_tree(void *root)
294 struct message_folder *folder = root;
300 g_free(folder->name);
302 tmp = folder->subfolders;
303 while (tmp != NULL) {
304 next = g_slist_next(tmp);
305 destroy_folder_tree(tmp->data);
308 g_slist_free(folder->subfolders);
312 static struct message_folder *create_folder(const char *name)
314 struct message_folder *folder = g_new0(struct message_folder, 1);
316 folder->name = g_strdup(name);
320 static void create_folder_tree()
323 struct message_folder *parent, *child;
325 folder_tree = create_folder("/");
327 parent = create_folder("telecom");
328 folder_tree->subfolders = g_slist_append(folder_tree->subfolders,
331 child = create_folder("msg");
332 parent->subfolders = g_slist_append(parent->subfolders, child);
335 int messages_init(void)
337 g_conn = dbus_bus_get(DBUS_BUS_SESSION, NULL);
339 error("Can't get on session bus");
346 void messages_exit(void)
349 dbus_connection_unref(g_conn);
354 static void message_get_folder_list(DBusMessage *reply, void *user_data)
356 DBusMessageIter iter;
357 DBusMessageIter iter_struct;
358 DBusMessageIter entry;
360 const char *name = NULL;
361 struct message_folder *parent = {0,}, *child = {0,};
366 for (l = folder_tree->subfolders; l != NULL; l = parent->subfolders)
369 DBG("Last child folder = %s \n", parent->name);
370 dbus_error_init(&derr);
372 if (dbus_set_error_from_message(&derr, reply)) {
373 error("Replied with an error: %s, %s", derr.name, derr.message);
374 dbus_error_free(&derr);
376 dbus_message_iter_init(reply, &iter);
377 dbus_message_iter_recurse(&iter, &iter_struct);
379 while (dbus_message_iter_get_arg_type(&iter_struct) ==
381 dbus_message_iter_recurse(&iter_struct, &entry);
383 dbus_message_iter_get_basic(&entry, &name);
384 DBG("Folder name = %s \n", name);
385 child = create_folder(name);
386 parent->subfolders = g_slist_append(parent->subfolders,
388 dbus_message_iter_next(&iter_struct);
391 dbus_message_unref(reply);
395 static void message_get_msg_list(DBusPendingCall *call, void *user_data)
397 DBusMessage *reply = dbus_pending_call_steal_reply(call);
398 DBusMessageIter iter;
399 DBusMessageIter iter_struct;
400 DBusMessageIter entry;
402 const char *msg_handle;
404 const char *datetime;
405 const char *sender_name;
406 const char *sender_addressing;
407 const char *replyto_addressing;
408 const char *recipient_name;
409 const char *recipient_addressing;
411 const char *reception_status;
413 const char *attachment_size;
423 uint8_t priority_val;
426 struct session *session = user_data;
427 struct messages_message *data = g_new0(struct messages_message, 1);
430 DBG("parameter_mask = %x; type = %d; period_begin = %s;"
431 "period_end = %s; read_status = %d; recipient = %s;"
432 "originator = %s; priority = %d",
433 session->filter->parameter_mask, session->filter->type,
434 session->filter->period_begin, session->filter->period_end,
435 session->filter->read_status, session->filter->recipient,
436 session->filter->originator, session->filter->priority);
438 dbus_error_init(&derr);
440 if (dbus_set_error_from_message(&derr, reply)) {
441 error("Replied with an error: %s, %s", derr.name, derr.message);
442 dbus_error_free(&derr);
443 session->msg_list_cb(session, -ENOENT, 0,
444 FALSE, data, session->user_data);
447 g_free(session->name);
448 session_filter_free(session->filter);
449 dbus_message_unref(reply);
454 dbus_message_iter_init(reply, &iter);
455 dbus_message_iter_get_basic(&iter, &newmessage);
456 dbus_message_iter_next(&iter);
457 dbus_message_iter_get_basic(&iter, &count);
458 dbus_message_iter_next(&iter);
460 if (session->max == 0)
463 dbus_message_iter_recurse(&iter, &iter_struct);
465 if (session->filter->parameter_mask == 0)
466 mask = ~session->filter->parameter_mask;
468 mask = session->filter->parameter_mask;
470 while (dbus_message_iter_get_arg_type(&iter_struct) ==
472 dbus_message_iter_recurse(&iter_struct, &entry);
473 dbus_message_iter_get_basic(&entry, &msg_handle);
475 if (msg_handle == NULL) {
476 dbus_message_iter_next(&iter_struct);
480 DBG("Msg handle = %s \n", msg_handle);
481 data->handle = g_strdup(msg_handle);
483 dbus_message_iter_next(&entry);
484 dbus_message_iter_get_basic(&entry, &subject);
486 if (mask & PMASK_SUBJECT) {
487 DBG("subject = %s\n", subject);
488 data->subject = g_strndup(subject,
489 BT_MAP_LIST_ITEM_MAX_LEN);
490 data->mask |= PMASK_SUBJECT;
493 dbus_message_iter_next(&entry);
494 dbus_message_iter_get_basic(&entry, &datetime);
496 if ((mask & PMASK_DATETIME) && (NULL != datetime)) {
497 DBG("datetime = %s\n", datetime);
498 char *begin = g_strdup(session->filter->period_begin);
499 char *end = g_strdup(session->filter->period_end);
500 char *time = g_strdup(datetime);
503 filter = __filter_timebased(begin, end, time);
509 if (TRUE == filter) {
510 data->datetime = g_strdup(datetime);
511 data->mask |= PMASK_DATETIME;
513 message_list_item_free(data);
514 dbus_message_iter_next(&iter_struct);
519 dbus_message_iter_next(&entry);
520 dbus_message_iter_get_basic(&entry, &sender_name);
522 if ((mask & PMASK_SENDER_NAME) &&
523 (NULL != session->filter->originator)) {
524 DBG("sender_name = %s \n", sender_name);
526 if (g_strstr_len(sender_name, -1,
527 session->filter->originator)) {
528 data->sender_name = g_strndup(sender_name,
529 BT_MAP_LIST_ITEM_MAX_LEN);
530 data->mask |= PMASK_SENDER_NAME;
532 message_list_item_free(data);
533 dbus_message_iter_next(&iter_struct);
538 dbus_message_iter_next(&entry);
539 dbus_message_iter_get_basic(&entry, &sender_addressing);
541 if ((mask & PMASK_SENDER_ADDRESSING) &&
542 (NULL != sender_addressing)) {
543 DBG("sender_addressing = %s \n", sender_addressing);
545 data->sender_addressing = g_strndup(sender_addressing,
546 BT_MAP_LIST_ITEM_MAX_LEN);
547 data->mask |= PMASK_SENDER_ADDRESSING;
550 dbus_message_iter_next(&entry);
551 dbus_message_iter_get_basic(&entry, &recipient_name);
553 if ((mask & PMASK_RECIPIENT_NAME) &&
554 (NULL != session->filter->recipient)) {
555 DBG("recipient_name = %s \n", recipient_name);
557 if (g_strstr_len(recipient_name, -1,
558 session->filter->recipient)) {
559 data->recipient_name =
560 g_strndup(recipient_name,
561 BT_MAP_LIST_ITEM_MAX_LEN);
562 data->mask |= PMASK_RECIPIENT_NAME;
564 message_list_item_free(data);
565 dbus_message_iter_next(&iter_struct);
570 dbus_message_iter_next(&entry);
571 dbus_message_iter_get_basic(&entry, &recipient_addressing);
573 if ((mask & PMASK_RECIPIENT_ADDRESSING) &&
574 (NULL != recipient_addressing)) {
575 DBG("recipient_addressing=%s\n", recipient_addressing);
577 data->recipient_addressing =
578 g_strndup(recipient_addressing,
579 BT_MAP_LIST_ITEM_MAX_LEN);
580 data->mask |= PMASK_RECIPIENT_ADDRESSING;
583 dbus_message_iter_next(&entry);
584 dbus_message_iter_get_basic(&entry, &type);
586 if ((mask & PMASK_TYPE) && (NULL != type)) {
587 DBG("type = %s \n", type);
589 type_val = get_type_val(type);
590 if (!(session->filter->type & type_val)) {
591 data->type = g_strdup(type);
592 data->mask |= PMASK_TYPE;
596 dbus_message_iter_next(&entry);
597 dbus_message_iter_get_basic(&entry, &size);
599 if ((mask & PMASK_SIZE) && (NULL != size)) {
600 DBG("size = %s \n", size);
602 data->size = g_strdup(size);
603 data->mask |= PMASK_SIZE;
606 dbus_message_iter_next(&entry);
607 dbus_message_iter_get_basic(&entry, &reception_status);
609 if (mask & PMASK_RECEPTION_STATUS) {
610 DBG("reception_status = %s \n", reception_status);
612 data->reception_status = g_strdup(reception_status);
613 data->mask |= PMASK_RECEPTION_STATUS;
616 dbus_message_iter_next(&entry);
617 dbus_message_iter_get_basic(&entry, &text);
619 if (mask & PMASK_TEXT) {
620 DBG("text = %d \n", text);
622 data->mask |= PMASK_TEXT;
625 dbus_message_iter_next(&entry);
626 dbus_message_iter_get_basic(&entry, &attachment_size);
628 if (mask & PMASK_ATTACHMENT_SIZE) {
629 DBG("attachment_size = %s\n", attachment_size);
631 data->attachment_size = g_strdup(attachment_size);
632 data->mask |= PMASK_ATTACHMENT_SIZE;
635 dbus_message_iter_next(&entry);
636 dbus_message_iter_get_basic(&entry, &priority);
638 if (mask & PMASK_PRIORITY) {
639 DBG("priority = %d \n", priority);
641 priority_val = get_priority_val(priority);
642 if ((session->filter->priority == 0) ||
643 (session->filter->priority & priority_val)) {
644 data->priority = priority;
645 data->mask |= PMASK_PRIORITY;
647 message_list_item_free(data);
648 dbus_message_iter_next(&iter_struct);
653 dbus_message_iter_next(&entry);
654 dbus_message_iter_get_basic(&entry, &read);
656 if (mask & PMASK_READ) {
657 DBG("read = %d \n", read);
659 read_val = get_read_status_val(read);
661 if ((session->filter->read_status == 0) ||
662 (session->filter->read_status & read_val)) {
664 data->mask |= PMASK_READ;
666 message_list_item_free(data);
667 dbus_message_iter_next(&iter_struct);
672 dbus_message_iter_next(&entry);
673 dbus_message_iter_get_basic(&entry, &sent);
675 if (mask & PMASK_SENT) {
676 DBG("sent = %d \n", sent);
678 data->mask |= PMASK_SENT;
681 dbus_message_iter_next(&entry);
682 dbus_message_iter_get_basic(&entry, &protect);
684 if (mask & PMASK_PROTECTED) {
685 DBG("protect = %d \n", protect);
686 data->protect = protect;
687 data->mask |= PMASK_PROTECTED;
690 dbus_message_iter_next(&entry);
691 dbus_message_iter_get_basic(&entry, &replyto_addressing);
693 if ((mask & PMASK_REPLYTO_ADDRESSING) &&
694 (0x04 == get_type_val(type))) {
696 DBG("replyto_addressing = %s \n", replyto_addressing);
697 if (replyto_addressing)
698 data->replyto_addressing =
699 g_strdup(replyto_addressing);
701 data->replyto_addressing = g_strdup("");
703 data->mask |= PMASK_REPLYTO_ADDRESSING;
706 session->msg_list_cb(session, -EAGAIN, 1, newmessage, data,
709 message_list_item_free(data);
710 dbus_message_iter_next(&iter_struct);
714 session->msg_list_cb(session, 0, count, newmessage, NULL,
718 g_free(session->name);
719 session_filter_free(session->filter);
720 dbus_message_unref(reply);
724 static void message_get_msg(DBusPendingCall *call, void *user_data)
726 DBusMessage *reply = dbus_pending_call_steal_reply(call);
727 DBusMessageIter iter;
729 struct session *session = user_data;
731 gboolean fraction_deliver;
735 dbus_error_init(&derr);
736 if (dbus_set_error_from_message(&derr, reply)) {
737 error("Replied with an error: %s, %s", derr.name, derr.message);
738 dbus_error_free(&derr);
740 dbus_message_iter_init(reply, &iter);
741 dbus_message_iter_get_basic(&iter, &fraction_deliver);
742 dbus_message_iter_next(&iter);
743 dbus_message_iter_get_basic(&iter, &msg_body);
744 DBG("msg_body %s\n", msg_body);
746 session->get_msg_cb(session, -EAGAIN, fraction_deliver,
747 msg_body, session->user_data);
748 session->get_msg_cb(session, 0, fraction_deliver,
749 NULL, session->user_data);
751 dbus_message_unref(reply);
755 int messages_connect(void **s)
757 DBusMessage *message;
762 struct session *session = g_new0(struct session, 1);
764 create_folder_tree();
766 session->cwd = g_strdup("/");
767 session->folder = folder_tree;
771 message = dbus_message_new_method_call(BT_MAP_SERVICE_NAME,
772 BT_MAP_SERVICE_OBJECT_PATH,
773 BT_MAP_SERVICE_INTERFACE,
774 QUERY_GET_FOLDER_TREE);
776 error("Can't allocate new message");
780 dbus_error_init(&err);
782 reply = dbus_connection_send_with_reply_and_block(g_conn, message,
783 DBUS_TIMEOUT_USE_DEFAULT, &err);
785 DBG(" Reply failed");
786 if (dbus_error_is_set(&err)) {
787 DBG("%s", err.message);
788 dbus_error_free(&err);
791 dbus_message_unref(message);
795 message_get_folder_list(reply, session);
797 dbus_message_unref(message);
802 void messages_disconnect(void *s)
804 DBusMessage *message;
805 struct session *session = s;
808 destroy_folder_tree(folder_tree);
810 g_free(session->cwd);
813 message = dbus_message_new_method_call(BT_MAP_SERVICE_NAME,
814 BT_MAP_SERVICE_OBJECT_PATH,
815 BT_MAP_SERVICE_INTERFACE,
816 QUERY_DESTROY_AGENT);
819 error("Can't allocate new message");
823 if (dbus_connection_send(g_conn, message, NULL) == FALSE)
824 error("Could not send dbus message");
826 dbus_message_unref(message);
831 static gboolean notification_registration(gpointer user_data)
834 DBusMessage *message = NULL;
836 struct mns_reg_data *data = (struct mns_reg_data *)user_data;
838 message = dbus_message_new_method_call(BT_MAP_SERVICE_NAME,
839 BT_MAP_SERVICE_OBJECT_PATH,
840 BT_MAP_SERVICE_INTERFACE,
841 QUERY_NOTI_REGISTRATION);
843 error("Can't allocate new message");
847 DBG("data->notification_status = %d\n", data->notification_status);
849 if (data->notification_status == 1)
854 dbus_message_append_args(message, DBUS_TYPE_STRING, &data->remote_addr,
855 DBUS_TYPE_BOOLEAN, ®,
858 if (dbus_connection_send(g_conn, message, NULL) == FALSE)
859 error("Could not send dbus message");
861 dbus_message_unref(message);
864 g_free(data->remote_addr);
871 int messages_set_notification_registration(void *session,
872 char *address, uint8_t status,
876 struct mns_reg_data *data = g_new0(struct mns_reg_data, 1);
877 data->notification_status = status;
878 data->remote_addr = g_strdup(address);
880 DBG("status = %d\n", status);
882 g_idle_add(notification_registration, data);
887 int messages_set_folder(void *s, const char *name, gboolean cdup)
889 struct session *session = s;
894 if (name && (strchr(name, '/') || strcmp(name, "..") == 0))
898 if (session->cwd[0] == 0)
901 newrel = g_path_get_dirname(session->cwd);
903 /* We use empty string for indication of the root directory */
904 if (newrel[0] == '.' && newrel[1] == 0)
909 if (!cdup && (!name || name[0] == 0))
910 newrel = g_strdup("");
912 newrel = g_build_filename(newrel ? newrel : session->cwd, name,
916 if (newrel[0] != '/')
917 newabs = g_build_filename("/", newrel, NULL);
919 newabs = g_strdup(newrel);
921 session->folder = get_folder(newabs);
922 if (session->folder == NULL) {
930 g_free(session->cwd);
931 session->cwd = newabs;
936 static gboolean async_get_folder_listing(void *s)
938 struct session *session = s;
940 uint16_t folder_list_size = 0;
942 struct message_folder *folder;
945 if (session->name && strchr(session->name, '/') != NULL)
948 path = g_build_filename(session->cwd, session->name, NULL);
950 if (path == NULL || strlen(path) == 0)
953 folder = get_folder(path);
958 if (session->max == 0) {
959 folder_list_size = g_slist_length(folder->subfolders);
963 dir = folder->subfolders;
966 for (i = 0; i < session->offset; i++) {
970 dir = g_slist_next(dir);
973 for (i = 0; i < session->max; i++) {
974 struct message_folder *dir_data;
979 dir_data = dir->data;
980 session->folder_list_cb(session, -EAGAIN, 0,
981 dir_data->name, session->user_data);
983 dir = g_slist_next(dir);
987 session->folder_list_cb(session, 0, folder_list_size,
988 NULL, session->user_data);
991 g_free(session->name);
996 int messages_get_folder_listing(void *s, const char *name,
997 uint16_t max, uint16_t offset,
998 messages_folder_listing_cb callback,
1002 struct session *session = s;
1003 session->name = g_strdup(name);
1005 session->offset = offset;
1006 session->folder_list_cb = callback;
1007 session->user_data = user_data;
1009 g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, async_get_folder_listing,
1016 int messages_get_messages_listing(void *session, const char *name,
1017 uint16_t max, uint16_t offset,
1018 uint8_t subject_len,
1019 const struct messages_filter *filter,
1020 messages_get_messages_listing_cb callback,
1023 DBusPendingCall *call;
1024 DBusMessage *message;
1025 struct session *s = session;
1027 if (name != NULL && strlen(name))
1028 s->name = g_strdup(name);
1030 s->name = g_strdup(s->cwd);
1035 s->filter = g_new0(struct messages_filter, 1);
1036 s->filter->parameter_mask = filter->parameter_mask;
1037 s->filter->type = filter->type;
1038 s->filter->period_begin = g_strdup(filter->period_begin);
1039 s->filter->period_end = g_strdup(filter->period_end);
1040 s->filter->read_status = filter->read_status;
1041 s->filter->recipient = g_strdup(filter->recipient);
1042 s->filter->originator = g_strdup(filter->originator);
1043 s->filter->priority = filter->priority;
1045 s->msg_list_cb = (void *)callback;
1046 s->user_data = user_data;
1048 message = dbus_message_new_method_call(BT_MAP_SERVICE_NAME,
1049 BT_MAP_SERVICE_OBJECT_PATH,
1050 BT_MAP_SERVICE_INTERFACE,
1051 QUERY_GET_MSG_LIST);
1053 error("Can't allocate new message");
1055 session_filter_free(s->filter);
1059 dbus_message_append_args(message, DBUS_TYPE_STRING, &s->name,
1060 DBUS_TYPE_UINT16, &s->max,
1063 if (dbus_connection_send_with_reply(g_conn, message, &call,
1064 DBUS_TIMEOUT_INFINITE) == FALSE) {
1065 error("Could not send dbus message");
1066 dbus_message_unref(message);
1068 session_filter_free(s->filter);
1071 dbus_pending_call_set_notify(call, message_get_msg_list, s, NULL);
1072 dbus_message_unref(message);
1077 int messages_push_message(void *session, const char *folder,
1078 uint8_t transparent, uint8_t retry,
1080 messages_push_message_cb callback,
1083 DBusMessage *message;
1086 struct session *s = session;
1088 gboolean save_copy = FALSE; /* As per specs default value */
1089 gboolean retry_send = TRUE; /* As per specs default value */
1090 gboolean native = FALSE;
1091 gchar *folder_path = NULL;
1096 DBG("session->cwd %s +\n", s->cwd);
1099 folder_path = g_strdup(folder);
1101 folder_path = g_strdup(s->cwd);
1103 s->push_msg_cb = callback;
1104 s->user_data = user_data;
1106 if (transparent & 0x1)
1109 if (!(retry & 0x1)) {
1111 DBG("Retry send %d\n", retry_send);
1114 if (charset & 0x1) {
1116 DBG("native send %d\n", native);
1119 DBG("save_copy %d\n", save_copy);
1120 DBG("retry_send %d\n", retry_send);
1121 DBG("native %d\n", native);
1123 message = dbus_message_new_method_call(BT_MAP_SERVICE_NAME,
1124 BT_MAP_SERVICE_OBJECT_PATH,
1125 BT_MAP_SERVICE_INTERFACE,
1126 QUERY_PUSH_MESSAGE);
1128 error("Can't allocate new message");
1129 g_free(folder_path);
1133 dbus_message_append_args(message, DBUS_TYPE_BOOLEAN, &save_copy,
1134 DBUS_TYPE_BOOLEAN, &retry_send,
1135 DBUS_TYPE_BOOLEAN, &native,
1136 DBUS_TYPE_STRING, &folder_path,
1139 dbus_error_init(&err);
1141 reply = dbus_connection_send_with_reply_and_block(
1143 DBUS_TIMEOUT_USE_DEFAULT, &err);
1145 DBG(" Reply failed");
1147 if (dbus_error_is_set(&err)) {
1148 DBG("%s", err.message);
1149 dbus_error_free(&err);
1151 g_free(folder_path);
1152 dbus_message_unref(message);
1156 if (!dbus_message_get_args(reply, &err, DBUS_TYPE_UINT64,
1157 &handle, DBUS_TYPE_INVALID)) {
1158 if (dbus_error_is_set(&err)) {
1159 error("err %s\n", err.message);
1160 dbus_error_free(&err);
1162 g_free(folder_path);
1163 dbus_message_unref(message);
1164 dbus_message_unref(reply);
1168 DBG("uint64 handle %"G_GUINT64_FORMAT"\n", handle);
1169 s->push_msg_cb(s, 0, handle, s->user_data);
1171 g_free(folder_path);
1172 dbus_message_unref(message);
1173 dbus_message_unref(reply);
1179 int messages_push_message_data(void *session, const char *bmsg, void *user_data)
1181 DBusMessage *message;
1185 message = dbus_message_new_method_call(BT_MAP_SERVICE_NAME,
1186 BT_MAP_SERVICE_OBJECT_PATH,
1187 BT_MAP_SERVICE_INTERFACE,
1188 QUERY_PUSH_MESSAGE_DATA);
1190 error("Can't allocate new message");
1194 dbus_message_append_args(message, DBUS_TYPE_STRING, &bmsg,
1197 if (dbus_connection_send(g_conn, message, NULL) == FALSE) {
1198 error("Could not send dbus message");
1199 dbus_message_unref(message);
1203 dbus_message_unref(message);
1208 int messages_get_message(void *session,
1210 uint8_t attachment, uint8_t charset,
1211 uint8_t fraction_request,
1212 messages_get_message_cb callback,
1215 DBusPendingCall *call;
1216 DBusMessage *message;
1217 struct session *s = session;
1219 gboolean attach = FALSE;
1220 gboolean transcode = FALSE;
1221 gboolean first_request = TRUE;
1225 if (NULL != handle) {
1226 message_name = g_strdup(handle);
1227 DBG("Message handle = %s\n", handle);
1231 s->get_msg_cb = callback;
1232 s->user_data = user_data;
1234 message = dbus_message_new_method_call(BT_MAP_SERVICE_NAME,
1235 BT_MAP_SERVICE_OBJECT_PATH,
1236 BT_MAP_SERVICE_INTERFACE,
1239 error("Can't allocate new message");
1240 g_free(message_name);
1244 if (attachment & 0x1)
1250 if (fraction_request & 0x1)
1251 first_request = FALSE;
1253 dbus_message_append_args(message, DBUS_TYPE_STRING, &message_name,
1254 DBUS_TYPE_BOOLEAN, &attach,
1255 DBUS_TYPE_BOOLEAN, &transcode,
1256 DBUS_TYPE_BOOLEAN, &first_request,
1259 if (dbus_connection_send_with_reply(g_conn, message, &call, -1) ==
1261 error("Could not send dbus message");
1262 dbus_message_unref(message);
1263 g_free(message_name);
1266 dbus_pending_call_set_notify(call, message_get_msg, s, NULL);
1267 dbus_message_unref(message);
1268 g_free(message_name);
1273 #ifndef SUPPORT_SMS_ONLY
1274 static void message_update_msg(DBusPendingCall *call, void *user_data)
1276 DBusMessage *reply = dbus_pending_call_steal_reply(call);
1277 DBusMessageIter iter;
1279 struct session *session = user_data;
1283 dbus_error_init(&derr);
1284 if (dbus_set_error_from_message(&derr, reply)) {
1285 error("Replied with an error: %s, %s", derr.name, derr.message);
1286 dbus_error_free(&derr);
1288 dbus_message_iter_init(reply, &iter);
1289 if (dbus_message_iter_get_arg_type(&iter) ==
1291 dbus_message_iter_get_basic(&iter, &err);
1292 DBG("Error : %d\n", err);
1293 session->msg_update_cb(session, err,
1294 session->user_data);
1297 dbus_message_unref(reply);
1302 int messages_update_inbox(void *session,
1303 messages_status_cb callback,
1306 #ifdef SUPPORT_SMS_ONLY
1307 /* MAP.TS.1.0.3 : TP/MMB/BV-16-I
1308 Currently support is only for SMS, Since SMS service does not
1309 allow the polling of its mailbox, it must return Not implemented */
1313 DBusPendingCall *call;
1314 DBusMessage *message;
1315 struct session *s = session;
1319 s->msg_update_cb = callback;
1320 s->user_data = user_data;
1322 message = dbus_message_new_method_call(BT_MAP_SERVICE_NAME,
1323 BT_MAP_SERVICE_OBJECT_PATH,
1324 BT_MAP_SERVICE_INTERFACE,
1325 QUERY_UPDATE_MESSAGE);
1327 error("Can't allocate new message");
1331 if (dbus_connection_send_with_reply(g_conn, message, &call, -1) ==
1333 error("Could not send dbus message");
1334 dbus_message_unref(message);
1337 dbus_pending_call_set_notify(call, message_update_msg, s, NULL);
1338 dbus_message_unref(message);
1344 static void message_status_msg(DBusPendingCall *call, void *user_data)
1346 DBusMessage *reply = dbus_pending_call_steal_reply(call);
1347 DBusMessageIter iter;
1349 struct session *session = user_data;
1354 dbus_error_init(&derr);
1355 if (dbus_set_error_from_message(&derr, reply)) {
1356 error("Replied with an error: %s, %s", derr.name, derr.message);
1357 dbus_error_free(&derr);
1359 dbus_message_iter_init(reply, &iter);
1360 if (dbus_message_iter_get_arg_type(&iter) ==
1362 dbus_message_iter_get_basic(&iter, &err);
1363 DBG("Error : %d\n", err);
1364 session->msg_status_cb(session, err,
1365 session->user_data);
1368 dbus_message_unref(reply);
1372 int messages_set_read(void *session, const char *handle, uint8_t value,
1373 messages_status_cb callback, void *user_data)
1375 DBusPendingCall *call;
1376 DBusMessage *message;
1377 struct session *s = session;
1386 DBG("Message handle = %s\n", handle);
1387 message_name = g_strdup(handle);
1389 s->msg_status_cb = callback;
1390 s->user_data = user_data;
1392 message = dbus_message_new_method_call(BT_MAP_SERVICE_NAME,
1393 BT_MAP_SERVICE_OBJECT_PATH,
1394 BT_MAP_SERVICE_INTERFACE,
1395 QUERY_SET_READ_STATUS);
1397 error("Can't allocate new message");
1398 g_free(message_name);
1402 read = value ? TRUE : FALSE;
1404 dbus_message_append_args(message, DBUS_TYPE_STRING, &message_name,
1405 DBUS_TYPE_BOOLEAN, &read,
1408 if (dbus_connection_send_with_reply(g_conn, message, &call, -1) ==
1410 error("Could not send dbus message");
1411 g_free(message_name);
1412 dbus_message_unref(message);
1416 dbus_pending_call_set_notify(call, message_status_msg, s, NULL);
1417 dbus_message_unref(message);
1418 g_free(message_name);
1423 int messages_set_delete(void *session, const char *handle,
1425 messages_status_cb callback,
1428 DBusPendingCall *call;
1429 DBusMessage *message;
1430 struct session *s = session;
1439 DBG("Message handle = %s\n", handle);
1440 message_name = g_strdup(handle);
1442 s->msg_status_cb = callback;
1443 s->user_data = user_data;
1445 message = dbus_message_new_method_call(BT_MAP_SERVICE_NAME,
1446 BT_MAP_SERVICE_OBJECT_PATH,
1447 BT_MAP_SERVICE_INTERFACE,
1448 QUERY_SET_DELETE_STATUS);
1450 error("Can't allocate new message");
1451 g_free(message_name);
1455 del = value ? TRUE : FALSE;
1457 dbus_message_append_args(message, DBUS_TYPE_STRING, &message_name,
1458 DBUS_TYPE_BOOLEAN, &del,
1461 if (dbus_connection_send_with_reply(g_conn, message, &call, -1) ==
1463 error("Could not send dbus message");
1464 g_free(message_name);
1465 dbus_message_unref(message);
1469 dbus_pending_call_set_notify(call, message_status_msg, s, NULL);
1470 dbus_message_unref(message);
1471 g_free(message_name);
1476 void messages_abort(void *session)