From 6c59792403dcb16d70c37286a1b7861b060b09d2 Mon Sep 17 00:00:00 2001 From: "paras.kumar" Date: Thu, 28 Apr 2016 20:39:04 +0530 Subject: [PATCH] GDBus Migration of MAP Agent Change-Id: I6c0e4e598f02d5dcf8f5dfea2e0101ca697a660e Signed-off-by: paras.kumar --- map-agent/CMakeLists.txt | 13 +- map-agent/bluetooth_map_agent.c | 2332 ++++++++++++++----------------------- map-agent/bluetooth_map_agent.h | 24 +- map-agent/bluetooth_map_agent.xml | 63 - map-agent/bluetooth_map_email.c | 1072 +++++++++++++++++ map-agent/bluetooth_map_email.h | 53 + map-agent/bluetooth_map_sms.c | 1188 +++++++++++++++++++ map-agent/bluetooth_map_sms.h | 51 + map-agent/bluetooth_map_types.h | 100 ++ map-agent/map_bmessage.c | 88 +- map-agent/map_bmessage.h | 4 +- packaging/bluetooth-agent.spec | 11 + 12 files changed, 3422 insertions(+), 1577 deletions(-) mode change 100755 => 100644 map-agent/bluetooth_map_agent.c create mode 100644 map-agent/bluetooth_map_email.c create mode 100644 map-agent/bluetooth_map_email.h create mode 100644 map-agent/bluetooth_map_sms.c create mode 100644 map-agent/bluetooth_map_sms.h create mode 100644 map-agent/bluetooth_map_types.h diff --git a/map-agent/CMakeLists.txt b/map-agent/CMakeLists.txt index 00d806e..f7062ad 100644 --- a/map-agent/CMakeLists.txt +++ b/map-agent/CMakeLists.txt @@ -1,27 +1,20 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.6) PROJECT(bluetooth-map-agent C) -SET(SRCS bluetooth_map_agent.c map_bmessage.c) +SET(SRCS bluetooth_map_agent.c bluetooth_map_sms.c bluetooth_map_email.c map_bmessage.c) INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}) INCLUDE(FindPkgConfig) pkg_check_modules(pkgs_map_agent REQUIRED - dbus-glib-1 dlog msg-service tapi vconf) + dlog msg-service email-service tapi vconf gio-2.0) FOREACH(flag ${pkgs_map_agent_CFLAGS}) SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") ENDFOREACH(flag) -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -fPIC -Wall -Werror") - -FIND_PROGRAM(DBUS_BINDING_TOOL NAMES dbus-binding-tool) -EXEC_PROGRAM("${DBUS_BINDING_TOOL}" - ARGS "--prefix=bluetooth_map \\ - ${CMAKE_CURRENT_SOURCE_DIR}/bluetooth_map_agent.xml \\ - --mode=glib-server \\ - --output=${CMAKE_CURRENT_SOURCE_DIR}/bluetooth_map_agent_glue.h") +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") ADD_EXECUTABLE(${PROJECT_NAME} ${SRCS}) TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_map_agent_LDFLAGS}) diff --git a/map-agent/bluetooth_map_agent.c b/map-agent/bluetooth_map_agent.c old mode 100755 new mode 100644 index fa87018..2d18a2c --- a/map-agent/bluetooth_map_agent.c +++ b/map-agent/bluetooth_map_agent.c @@ -26,8 +26,7 @@ #include #include #include -#include -#include +#include #include #include "vconf.h" #include "vconf-keys.h" @@ -47,30 +46,15 @@ #include #include #include +#include +#include #include #define OBEX_CLIENT_SERVICE "org.bluez.obex" #define OBEX_CLIENT_INTERFACE "org.bluez.obex.Client1" #define OBEX_CLIENT_PATH "/org/bluez/obex" - #define MNS_CLIENT_INTERFACE "org.openobex.MessageNotification" -#define DBUS_STRUCT_STRING_STRING_UINT (dbus_g_type_get_struct("GValueArray", \ - G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID)) - -#define DBUS_STRUCT_MESSAGE_LIST (dbus_g_type_get_struct("GValueArray", \ - G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, \ - G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, \ - G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_STRING, \ - G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, \ - G_TYPE_BOOLEAN, G_TYPE_STRING, \ - G_TYPE_INVALID)) - -static msg_handle_t g_msg_handle = NULL; -static TapiHandle *g_tapi_handle = NULL; -static TelSmsAddressInfo_t *g_sca_info = NULL; -static DBusGProxy *g_mns_proxy; - #define BT_MAP_NEW_MESSAGE "NewMessage" #define BT_MAP_STATUS_CB "sent status callback" #define BT_MAP_MSG_CB "sms message callback" @@ -82,33 +66,18 @@ static DBusGProxy *g_mns_proxy; #define BT_MAP_MSG_INFO_MAX 256 #define BT_MAP_MSG_HANDLE_MAX 21 #define BT_MAP_TIMESTAMP_MAX_LEN 16 -#define BT_MAP_SUBJECT_MAX_LEN 50 #define BT_MAP_MSG_BODY_MAX 1024 #define BT_MSG_UPDATE 0 #define BT_MSG_DELETE 1 #define BT_SMS 0 -#define BEGIN_BMSEG "BEGIN:BMSG\r\n" -#define END_BMSEG "END:BMSG\r\n" -#define BMSEG_VERSION "VERSION:1.0\r\n" -#define MSEG_STATUS "STATUS:%s\r\n" -#define MSEG_TYPE "TYPE:%s\r\n" -#define FOLDER_PATH "FOLDER:%s\r\n" -#define VCARD "BEGIN:VCARD\r\nVERSION:2.1\r\nN:%s\r\nTEL:%s\r\nEND:VCARD\r\n" -#define BEGIN_BENV "BEGIN:BENV\r\n" -#define END_BENV "END:BENV\r\n" -#define BEGIN_BBODY "BEGIN:BBODY\r\n" -#define END_BBODY "END:BBODY\r\n" -#define ENCODING "ENCODING:%s\r\n" -#define CHARSET "CHARSET:%s\r\n" -#define LANGUAGE "LANGUAGE:%s\r\n" -#define LENGTH "LENGTH:%d\r\n" -#define MSG_BODY "BEGIN:MSG\r\n%s\r\nEND:MSG\r\n" -#define MSG_BODY_BEGIN "BEGIN:MSG\r\n" -#define MSG_BODY_END "\r\nEND:MSG\r\n" +static TapiHandle *g_tapi_handle; +static TelSmsAddressInfo_t *g_sca_info; GSList *id_list = NULL; guint64 current_push_map_id; +char *push_folder; +msg_send_option_t opt; typedef enum { SMS_TON_UNKNOWN = 0, /* unknown */ @@ -124,215 +93,342 @@ typedef enum { struct id_info { guint64 map_id; int uid; + int msg_type; }; -struct msg_send_option { - bool save_copy; - bool retry_send; - bool native; -}; - -struct message_info { - char *handle; - char *subject; - char *datetime; - char *sender_name; - char *sender_addressing; - char *recipient_name; - char *recipient_addressing; - char *type; - char *size; - char *reception_status; - char *attachment_size; - char *replyto_addressing; - gboolean text; - gboolean priority; - gboolean read; - gboolean sent; - gboolean protect; -}; - -typedef struct { - GObject parent; -} BluetoothMapAgent; - -typedef struct { - GObjectClass parent; -} BluetoothMapAgentClass; - -GType bluetooth_map_agent_get_type(void); - -#define BLUETOOTH_MAP_TYPE_AGENT (bluetooth_map_agent_get_type()) - -#define BLUETOOTH_MAP_AGENT(object) \ - (G_TYPE_CHECK_INSTANCE_CAST((object), \ - BLUETOOTH_MAP_TYPE_AGENT , BluetoothMapAgent)) -#define BLUETOOTH_MAP_AGENT_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), \ - BLUETOOTH_MAP_TYPE_AGENT , BluetoothMapAgentClass)) -#define BLUETOOTH_MAP_IS_AGENT(object) \ - (G_TYPE_CHECK_INSTANCE_TYPE((object), \ - BLUETOOTH_MAP_TYPE_AGENT)) -#define BLUETOOTH_MAP_IS_AGENT_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), \ - BLUETOOTH_MAP_TYPE_AGENT)) -#define BLUETOOTH_MAP_AGENT_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS((obj), \ - BLUETOOTH_MAP_TYPE_AGENT , BluetoothMapAgentClass)) - -G_DEFINE_TYPE(BluetoothMapAgent, bluetooth_map_agent, G_TYPE_OBJECT) - -GMainLoop *g_mainloop = NULL; -static DBusGConnection *g_connection = NULL; -static char *g_mns_path = NULL; -static struct msg_send_option opt; - -static gboolean bluetooth_map_get_folder_tree(BluetoothMapAgent *agent, - DBusGMethodInvocation *context); -static gboolean bluetooth_map_get_message_list(BluetoothMapAgent *agent, - gchar *folder_name, guint16 max, - DBusGMethodInvocation *context); -static gboolean bluetooth_map_get_message(BluetoothMapAgent *agent, - gchar *message_name, - gboolean attach, gboolean transcode, - gboolean first_request, - DBusGMethodInvocation *context); -static gboolean bluetooth_map_push_message(BluetoothMapAgent *agent, - gboolean save_copy, - gboolean retry_send, - gboolean native, - gchar *folder_name, - DBusGMethodInvocation *context); -static gboolean bluetooth_map_push_message_data(BluetoothMapAgent *agent, - gchar *bmsg, - DBusGMethodInvocation *context); -static gboolean bluetooth_map_update_message(BluetoothMapAgent *agent, - DBusGMethodInvocation *context); -static gboolean bluetooth_map_set_read_status(BluetoothMapAgent *agent, - gchar *handle, gboolean read_status, - DBusGMethodInvocation *context); -static gboolean bluetooth_map_set_delete_status(BluetoothMapAgent *agent, - gchar *handle, gboolean delete_status, - DBusGMethodInvocation *context); -static gboolean bluetooth_map_noti_registration(BluetoothMapAgent *agent, - gchar *remote_addr, - gboolean status, - DBusGMethodInvocation *context); -static gboolean bluetooth_map_destroy_agent(BluetoothMapAgent *agent, - DBusGMethodInvocation *context); - -#include "bluetooth_map_agent_glue.h" - -static void bluetooth_map_agent_init(BluetoothMapAgent *obj) +/* Store supported folders in SMS and EMAIL */ +gboolean folders_supported[FOLDER_COUNT][MSG_TYPES] = { {FALSE, FALSE}, }; + +GMainLoop *g_mainloop; +static char *g_mns_path; +static GDBusConnection *map_dbus_conn; +static GDBusProxy *g_mns_proxy; + +static const gchar map_agent_introspection_xml[] = +"" +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +""; + +/* Method Prototypes */ +static GVariant *__bt_map_get_folder_tree(GError **err); +static GVariant *__bt_map_get_message_list(char *folder_name, guint16 max, + guint16 offset, guint8 subject_len, + map_msg_filter_t *filter, GError **err); +static GVariant *__bt_map_get_message(char *message_name, gboolean attach, + gboolean transcode, gboolean first_request, GError **err); +static GVariant *__bt_map_push_message(gboolean save_copy, gboolean retry_send, + gboolean native, char *folder_name, GError **err); +static GVariant *__bt_map_push_message_data(char *bmseg, GError **err); +static GVariant *__bt_map_update_message(GError **err); +static GVariant *__bt_map_set_read_status(char *handle, gboolean read_status, GError **err); +static GVariant *__bt_map_set_delete_status(char *handle, gboolean delete_status, GError **err); +static void __bt_map_noti_registration(char *remote_addr, gboolean status); +static void __bt_map_destroy_agent(void); + +/* Create GError from error code and error message */ +static GError *__bt_map_error(int error_code, char *error_message) { - FN_START; - g_assert(obj != NULL); - FN_END; + return g_error_new(g_quark_from_string("MAP Agent"), + error_code, "MAP Agent Error: %s", error_message); } -static void bluetooth_map_agent_finalize(GObject *obj) +static map_msg_filter_t __bt_map_get_filters(GVariant *filters) { - FN_START; - G_OBJECT_CLASS(bluetooth_map_agent_parent_class)->finalize(obj); - FN_END; + map_msg_filter_t filter = { 0, }; + GVariantIter iter; + GVariant *value; + gchar *key; + + g_variant_iter_init(&iter, filters); + while (g_variant_iter_loop(&iter, "{sv}", &key, &value)) { + if (!g_strcmp0(key, "ParameterMask")) { + filter.parameter_mask = g_variant_get_uint32(value); + DBG("ParameterMask :%u", filter.parameter_mask); + } else if (!g_strcmp0(key, "FilterMessageType")) { + filter.type = g_variant_get_byte(value); + DBG("FilterMessageType :%u", filter.type); + } else if (!g_strcmp0(key, "FilterPeriodBegin")) { + g_variant_get(value, "s", &filter.period_begin); + DBG("FilterPeriodBegin :%s", filter.period_begin); + } else if (!g_strcmp0(key, "FilterPeriodEnd")) { + g_variant_get(value, "s", &filter.period_end); + DBG("FilterPeriodEnd :%s", filter.period_end); + } else if (!g_strcmp0(key, "FilterReadStatus")) { + filter.read_status = g_variant_get_byte(value); + DBG("FilterReadStatus :%u", filter.read_status); + } else if (!g_strcmp0(key, "FilterRecipient")) { + g_variant_get(value, "s", &filter.recipient); + DBG("FilterRecipient :%s", filter.recipient); + } else if (!g_strcmp0(key, "FilterOriginator")) { + g_variant_get(value, "s", &filter.originator); + DBG("FilterOriginator :%s", filter.originator); + } else if (!g_strcmp0(key, "FilterPriority")) { + filter.priority = g_variant_get_byte(value); + DBG("FilterPriority :%u", filter.priority); + } + } + + return filter; } -static void bluetooth_map_agent_class_init(BluetoothMapAgentClass *klass) +static void __bt_map_agent_method(GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *method_name, + GVariant *parameters, + GDBusMethodInvocation *invocation, + gpointer user_data) { FN_START; - GObjectClass *object_class = (GObjectClass *) klass; - g_assert(klass != NULL); + INFO("method %s", method_name); + INFO("object_path %s", object_path); + GError *err = NULL; - object_class->finalize = bluetooth_map_agent_finalize; + if (g_strcmp0(method_name, "GetFolderTree") == 0) { + GVariant *folder_list = NULL; - dbus_g_object_type_install_info(BLUETOOTH_MAP_TYPE_AGENT, - &dbus_glib_bluetooth_map_object_info); - FN_END; -} + folder_list = __bt_map_get_folder_tree(&err); + if (err) + goto fail; -static GQuark __bt_map_agent_error_quark(void) -{ - FN_START; - static GQuark quark = 0; - if (!quark) - quark = g_quark_from_static_string("agent"); + g_dbus_method_invocation_return_value(invocation, folder_list); + } else if (g_strcmp0(method_name, "GetMessageList") == 0) { + GVariant *message_list = NULL; + guint16 max; + guint16 offset; + guint8 subject_len; + gchar *folder_name; + GVariant *filters = NULL; + map_msg_filter_t filter = { 0, }; - FN_END; - return quark; -} + g_variant_get(parameters, "(&sqqy@a{sv})", &folder_name, + &max, &offset, &subject_len, &filters); -static GError *__bt_map_agent_error(bt_map_agent_error_t error, - const char *err_msg) -{ - FN_START; - return g_error_new(BT_MAP_AGENT_ERROR, error, err_msg, NULL); + DBG("MAX:%d Offset:%d SubjectLen:%d", max, offset, subject_len); + if (subject_len == 0) + subject_len = BT_MAP_SUBJECT_MAX_LEN; + + filter = __bt_map_get_filters(filters); + message_list = __bt_map_get_message_list(folder_name, max, + offset, subject_len, &filter, &err); + + if (err) + goto fail; + + g_dbus_method_invocation_return_value(invocation, message_list); + } else if (g_strcmp0(method_name, "GetMessage") == 0) { + GVariant *message = NULL; + gchar *message_name; + gboolean attach; + gboolean transcode; + gboolean first_request; + + g_variant_get(parameters, "(&sbbb)", &message_name, + &attach, &transcode, &first_request); + + message = __bt_map_get_message(message_name, attach, + transcode, first_request, &err); + if (err) + goto fail; + + g_dbus_method_invocation_return_value(invocation, message); + } else if (g_strcmp0(method_name, "PushMessage") == 0) { + GVariant *handle = NULL; + gboolean save_copy; + gboolean retry_send; + gboolean native; + gchar *folder_name; + + g_variant_get(parameters, "(bbb&s)", &save_copy, + &retry_send, &native, &folder_name); + + handle = __bt_map_push_message(save_copy, retry_send, + native, folder_name, &err); + if (err) + goto fail; + + g_dbus_method_invocation_return_value(invocation, handle); + } else if (g_strcmp0(method_name, "PushMessageData") == 0) { + gchar *bmseg; + + g_variant_get(parameters, "(&s)", &bmseg); + + __bt_map_push_message_data(bmseg, &err); + if (err) + goto fail; + + g_dbus_method_invocation_return_value(invocation, NULL); + } else if (g_strcmp0(method_name, "UpdateMessage") == 0) { + GVariant *update = NULL; + + update = __bt_map_update_message(&err); + if (err) + goto fail; + + g_dbus_method_invocation_return_value(invocation, update); + } else if (g_strcmp0(method_name, "SetReadStatus") == 0) { + gchar *handle; + gboolean read_status; + + g_variant_get(parameters, "(&sb)", &handle, &read_status); + + __bt_map_set_read_status(handle, read_status, &err); + if (err) + goto fail; + + g_dbus_method_invocation_return_value(invocation, NULL); + } else if (g_strcmp0(method_name, "SetDeleteStatus") == 0) { + gchar *handle; + gboolean delete_status; + + g_variant_get(parameters, "(&sb)", &handle, &delete_status); + + __bt_map_set_delete_status(handle, delete_status, &err); + if (err) + goto fail; + + g_dbus_method_invocation_return_value(invocation, NULL); + } else if (g_strcmp0(method_name, "NotiRegistration") == 0) { + char *remote_addr; + gboolean status; + g_variant_get(parameters, "(&sb)", &remote_addr, &status); + + __bt_map_noti_registration(remote_addr, status); + g_dbus_method_invocation_return_value(invocation, NULL); + } else if (g_strcmp0(method_name, "DestroyAgent") == 0) { + g_dbus_method_invocation_return_value(invocation, NULL); + __bt_map_destroy_agent(); + } + + INFO("-"); + return; + +fail: + g_dbus_method_invocation_return_gerror(invocation, err); + g_error_free(err); + INFO("-"); } -static void __bt_mns_client_event_notify(gchar *event, guint64 handle, - gchar *folder, gchar *old_folder, - gchar *msg_type); +static const GDBusInterfaceVTable method_table = { + __bt_map_agent_method, + NULL, + NULL, +}; -static char *__bt_get_truncated_utf8_string(char *src) +static GDBusConnection *__bt_map_get_gdbus_connection(void) { FN_START; - char *p = src; - char *next; - char dest[BT_MAP_SUBJECT_MAX_LEN] = {0,}; - int count; - int i = 0; - if (src == NULL) - return FALSE; + GError *err = NULL; - while (*p != '\0' && i < sizeof(dest)) { - next = g_utf8_next_char(p); - count = next - p; + if (map_dbus_conn) + return map_dbus_conn; - while (count > 0 && ((i + count) < sizeof(dest))) { - dest[i++] = *p; - p++; - count --; + map_dbus_conn = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, &err); + if (!map_dbus_conn) { + if (err) { + ERR("Unable to connect to dbus: %s", err->message); + g_clear_error(&err); } - p = next; + return NULL; } FN_END; - return g_strdup(dest); + return map_dbus_conn; +} + +gboolean is_mns_connected(void) +{ + if (!g_mns_proxy) + return FALSE; + else + return TRUE; } -static guint64 __bt_validate_uid(int uid) +guint64 _bt_validate_uid(int uid, int msg_type) { FN_START; struct id_info *info; - int count; - int i; + GSList *list = id_list; - count = g_slist_length(id_list); - for (i = 0; i < count; i++) { - info = (struct id_info *)g_slist_nth_data(id_list, i); - if (!info) - break; + while (list) { + info = list->data; - if (info->uid == uid) { - DBG("uid = %d\n", uid); + if (info && info->uid == uid && info->msg_type == msg_type) { + DBG("UID = %d, MessageType=%d", uid, msg_type); return info->map_id; } + + list = g_slist_next(list); } FN_END; return 0; } -static guint64 __bt_add_id(int uid) +guint64 _bt_add_id(int uid, int msg_type) { FN_START; static guint64 map_id; struct id_info *info; guint64 test; - DBG("Add id: %d\n", uid); - test = __bt_validate_uid(uid); + DBG("Add id: %d, MsgType:%d", uid, msg_type); + test = _bt_validate_uid(uid, msg_type); DBG("test: %llx\n", test); if (test) return test; @@ -343,7 +439,8 @@ static guint64 __bt_add_id(int uid) info->map_id = map_id; info->uid = uid; - DBG("map_id = %llx, uid = %d \n", info->map_id, info->uid); + info->msg_type = msg_type; + DBG("map_id = %llx, uid = %d, MsgType=%d", info->map_id, info->uid, msg_type); id_list = g_slist_append(id_list, info); @@ -351,61 +448,60 @@ static guint64 __bt_add_id(int uid) return map_id; } -static int __bt_get_id(guint64 map_id) +static struct id_info *__bt_get_id(guint64 map_id) { FN_START; struct id_info *info; - int count; - int i; - - count = g_slist_length(id_list); + GSList *list = id_list; - for (i = 0; i < count; i++) { - info = (struct id_info *)g_slist_nth_data(id_list, i); + while (list) { + info = list->data; if (info->map_id == map_id) - return info->uid; + return info; + + list = g_slist_next(list); } FN_END; - return -1; + return NULL; } -static int __bt_get_uid(gchar *handle) +static struct id_info *__bt_get_uid(gchar *handle) { FN_START; guint64 map_id; - int uid; + struct id_info *handle_info; - if (NULL == handle) - return -1; + if (handle == NULL) + return NULL; map_id = g_ascii_strtoull(handle, NULL, 16); if (!map_id) - return -1; + return NULL; - uid = __bt_get_id(map_id); + handle_info = __bt_get_id(map_id); FN_END; - return uid; + return handle_info; } -static int __bt_update_id(guint64 map_id, int new_uid) +int _bt_update_id(guint64 map_id, int new_uid, int msg_type) { FN_START; struct id_info *info; - int i; - int count; + GSList *list = id_list; - count = g_slist_length(id_list); - - for (i = 0; i < count; i++) { - info = g_slist_nth_data(id_list, i); + while (list) { + info = list->data; if (info->map_id == map_id) { info->uid = new_uid; + info->msg_type = msg_type; return map_id; } + + list = g_slist_next(list); } FN_END; @@ -423,146 +519,57 @@ static void __bt_remove_list(GSList *id_list) FN_END; } -static int __bt_get_folder_id(char *folder_path) +gboolean _bt_verify_sender(message_info_t *msg_info, char *sender) { - FN_START; - int folder_id = -1; - int i; - char *folder; - msg_struct_list_s folder_list = {0,}; - msg_error_t err; - msg_struct_t p_folder; - DBG_SECURE("folder_path %s\n", folder_path); - - folder = strrchr(folder_path, '/'); - if (NULL == folder) - folder = folder_path; - else - folder++; - - err = msg_get_folder_list(g_msg_handle, &folder_list); - if (err != MSG_SUCCESS) - goto done; - - for (i = 0; i < folder_list.nCount; i++) { - char folder_name[BT_MAP_MSG_INFO_MAX] = {0, }; + if (!sender) + return TRUE; - p_folder = folder_list.msg_struct_info[i]; + if (!g_strcmp0(sender, "*")) + return TRUE; - err = msg_get_str_value(p_folder, MSG_FOLDER_INFO_NAME_STR, - folder_name, BT_MAP_MSG_INFO_MAX); - if (err != MSG_SUCCESS) - continue; + if (g_strrstr(msg_info->sender_name, sender) || + g_strrstr(msg_info->sender_addressing, sender)) + return TRUE; - DBG_SECURE("folder_name %s\n", folder_name); - if (!g_ascii_strncasecmp(folder_name, folder, strlen(folder))) { - err = msg_get_int_value(p_folder, - MSG_FOLDER_INFO_ID_INT, - &folder_id); - if (err != MSG_SUCCESS) - goto done; + return FALSE; +} - DBG("folder_id %d", folder_id); - break; - } - } +gboolean _bt_verify_receiver(message_info_t *msg_info, char *receiver) +{ + if (!receiver) + return TRUE; -done: - if (folder_list.msg_struct_info) - msg_release_list_struct(&folder_list); + if (!g_strcmp0(receiver, "*")) + return TRUE; - FN_END; - return folder_id; + if (g_strrstr(msg_info->recipient_name, receiver) || + g_strrstr(msg_info->recipient_addressing, receiver)) + return TRUE; + return FALSE; } -static void __bt_add_deleted_folder(void) +gboolean _bt_verify_read_status(message_info_t *msg_info, guint8 read_status) { - FN_START; - msg_error_t err; - msg_struct_t folder_info = msg_create_struct(MSG_STRUCT_FOLDER_INFO); - - err = msg_set_int_value(folder_info, MSG_FOLDER_INFO_TYPE_INT, - MSG_FOLDER_TYPE_USER_DEF); - if (err != MSG_SUCCESS) { - ERR("Failed adding type %d", err); - msg_release_struct(&folder_info); - return; - } - - err = msg_set_str_value(folder_info, MSG_FOLDER_INFO_NAME_STR, - "DELETED", MAX_FOLDER_NAME_SIZE); - if (err != MSG_SUCCESS) { - ERR("Failed adding str %d", err); - msg_release_struct(&folder_info); - return; - } - - err = msg_add_folder(g_msg_handle, folder_info); - if (err != MSG_SUCCESS) { - ERR("Failed adding folder %d", err); - msg_release_struct(&folder_info); - return; - } + if (read_status == FILTER_READ_STATUS_ALL || + ((read_status == FILTER_READ_STATUS_UNREAD) && msg_info->read == FALSE) || + ((read_status == FILTER_READ_STATUS_READ) && msg_info->read == TRUE)) + return TRUE; - msg_release_struct(&folder_info); - FN_END; + return FALSE; } -static gchar *__bt_get_folder_name(int id) +gboolean _bt_filter_priority(message_info_t *msg_info, guint8 priority) { - FN_START; - int ret; - int i; - int folder_id; - gboolean path_found = FALSE; - char folder_name[BT_MAP_MSG_INFO_MAX] = {0,}; - - msg_struct_list_s folder_list = {0,}; - msg_struct_t p_folder; - - ret = msg_get_folder_list(g_msg_handle, &folder_list); - if (ret != MSG_SUCCESS) - return g_strdup("TELECOM/MSG"); - - if (folder_list.msg_struct_info == NULL) - return g_strdup("TELECOM/MSG"); - - for (i = 0; i < folder_list.nCount; i++) { - p_folder = folder_list.msg_struct_info[i]; - - ret = msg_get_int_value(p_folder, - MSG_FOLDER_INFO_ID_INT, - &folder_id); - if (ret != MSG_SUCCESS) - break; - DBG("folder_id %d, id = %d", folder_id, id); - if (folder_id == id) { - ret = msg_get_str_value(p_folder, - MSG_FOLDER_INFO_NAME_STR, - folder_name, BT_MAP_MSG_INFO_MAX); - if (ret != MSG_SUCCESS) - break; - - path_found = TRUE; - DBG_SECURE("folder_name %s", folder_name); - break; - } - } - - if (folder_list.msg_struct_info) { - ret = msg_release_list_struct(&folder_list); - ERR("Err %d", ret); - } + if (priority == FILTER_PRIORITY_ALL || + ((priority == FILTER_PRIORITY_HIGH) && msg_info->priority == TRUE) || + ((priority == FILTER_PRIORITY_LOW) && msg_info->priority == FALSE)) + return TRUE; - FN_END; - if (path_found != TRUE) - return g_strdup("TELECOM/MSG"); - else - return g_strdup_printf("TELECOM/MSG/%s", folder_name); + return FALSE; } -static void __get_msg_timestamp(time_t *ltime, char *timestamp) +void _get_msg_timestamp(time_t *ltime, char *timestamp) { FN_START; struct tm local_time; @@ -579,7 +586,54 @@ static void __get_msg_timestamp(time_t *ltime, char *timestamp) local_time.tm_min, local_time.tm_sec); FN_END; - return; +} + +time_t _get_time_t_from_timestamp(char *timestamp) +{ + struct tm local_time; + int year; + int month; + time_t int_time; + + sscanf(timestamp, "%04d%02d%02dT%02d%02d%02d", &year, &month, + &local_time.tm_mday, &local_time.tm_hour, + &local_time.tm_min, &local_time.tm_sec); + + local_time.tm_year = year - 1900; + local_time.tm_mon = month - 1; + + int_time = mktime(&local_time); + return int_time; +} + +gboolean _bt_verify_time(message_info_t *msg_info, map_msg_filter_t *filter) +{ + struct tm local_time = { 0, }; + time_t start; + time_t end; + + /* Set 19710101T000000 as Start Date */ + local_time.tm_year = 1971 - 1900; + local_time.tm_mon = 0; + local_time.tm_mday = 1; + start = mktime(&local_time); + + /* Set 20380101T000000 as End Date */ + local_time.tm_year = 2038 - 1900; + local_time.tm_mon = 0; + local_time.tm_mday = 1; + end = mktime(&local_time); + + if (filter->period_begin) + start = _get_time_t_from_timestamp(filter->period_begin); + + if (filter->period_end) + end = _get_time_t_from_timestamp(filter->period_end); + + if (msg_info->time >= start && msg_info->time <= end) + return TRUE; + + return FALSE; } #define SET_TON_NPI(dest, ton, npi) { \ @@ -744,7 +798,7 @@ static int __bt_sms_encode_time(gchar *addr_field, time_t *tm) return index; } -static gchar *__bt_get_sms_pdu_from_msg_data(gchar *number, +gchar *__bt_get_sms_pdu_from_msg_data(gchar *number, char *msg, time_t tm, int *msg_pdu_len) { @@ -811,1058 +865,475 @@ static void __bt_get_sms_sca(TapiHandle *handle, int result, void *data, FN_END; } -static char *__bt_prepare_msg_bmseg(msg_struct_t msg_info, gboolean attach, - gboolean transcode) +void _bt_message_info_free(gpointer data) { FN_START; - int ret; - int m_type = MSG_TYPE_SMS; - int folder_id; - int count; - int dptime = 0; - int j; - bool read_status = false; - char msg_body[BT_MAP_MSG_BODY_MAX] = {0,}; - char addr_value[MAX_ADDRESS_VAL_LEN] = {0,}; - char name_value[MAX_DISPLAY_NAME_LEN] = {0,}; - - msg_list_handle_t addr_list = NULL; - msg_struct_t addr_info = NULL; - - GString *msg; - gchar *folder_path = NULL; - gchar *msg_pdu; - - msg = g_string_new(BEGIN_BMSEG); - g_string_append(msg, BMSEG_VERSION); - - ret = msg_get_bool_value(msg_info, MSG_MESSAGE_READ_BOOL, &read_status); - if (ret == MSG_SUCCESS) { - INFO("read_status %d\n", read_status); - } - - if (read_status) - g_string_append_printf(msg, MSEG_STATUS, "READ"); - else - g_string_append_printf(msg, MSEG_STATUS, "UNREAD"); - - ret = msg_get_int_value(msg_info, MSG_MESSAGE_TYPE_INT, &m_type); - if (ret == MSG_SUCCESS) { - INFO("m_type %d\n", m_type); - g_string_append_printf(msg, MSEG_TYPE, "SMS_GSM"); - } - - ret = msg_get_int_value(msg_info, MSG_MESSAGE_FOLDER_ID_INT, - &folder_id); - if (ret == MSG_SUCCESS) { - DBG("folder_id %d\n", folder_id); - - folder_path = __bt_get_folder_name(folder_id); - g_string_append_printf(msg, FOLDER_PATH, folder_path); - } - - ret = msg_get_list_handle(msg_info, MSG_MESSAGE_ADDR_LIST_HND, - (void **)&addr_list); - if (ret == MSG_SUCCESS) { - count = msg_list_length(addr_list); - DBG("count %d \n", count); - - if (count > 0) { - addr_info = (msg_struct_t)msg_list_nth_data(addr_list, - 0); - - msg_get_str_value(addr_info, - MSG_ADDRESS_INFO_ADDRESS_VALUE_STR, - addr_value, MAX_ADDRESS_VAL_LEN); - DBG_SECURE("addr_value %s\n", addr_value); - msg_get_str_value(addr_info, - MSG_ADDRESS_INFO_DISPLAYNAME_STR, - name_value, MAX_DISPLAY_NAME_LEN); - if (!strlen(name_value)) - g_stpcpy(name_value, addr_value); - - DBG_SECURE("name_value %s\n", name_value); - - g_string_append_printf(msg, VCARD, name_value, - addr_value); - } - } - - g_string_append(msg, BEGIN_BENV); - g_string_append(msg, BEGIN_BBODY); - - if (transcode) { - g_string_append_printf(msg, CHARSET, "UTF-8"); - + message_info_t *msg_info = (message_info_t *)data; + g_free(msg_info->handle); + g_free(msg_info->subject); + g_free(msg_info->datetime); + g_free(msg_info->sender_name); + g_free(msg_info->sender_addressing); + g_free(msg_info->replyto_addressing); + g_free(msg_info->recipient_name); + g_free(msg_info->recipient_addressing); + g_free(msg_info->type); + g_free(msg_info->reception_status); + g_free(msg_info->size); + g_free(msg_info->attachment_size); + g_free(msg_info); + FN_END; +} - ret = msg_get_str_value(msg_info, - MSG_MESSAGE_SMS_DATA_STR, - msg_body, BT_MAP_MSG_BODY_MAX); - if (ret == MSG_SUCCESS) { - g_string_append_printf(msg, LENGTH, (int)strlen(msg_body)); - g_string_append_printf(msg, MSG_BODY, msg_body); - } - } else { - g_string_append_printf(msg, ENCODING, "G-7BIT"); - g_string_append_printf(msg, CHARSET, "native"); - - msg_get_int_value(msg_info, - MSG_MESSAGE_DISPLAY_TIME_INT, &dptime); - - ret = msg_get_str_value(msg_info, MSG_MESSAGE_SMS_DATA_STR, - msg_body, BT_MAP_MSG_BODY_MAX); - if (ret == MSG_SUCCESS) { - int msg_pdu_len = 0; - msg_pdu = __bt_get_sms_pdu_from_msg_data(addr_value, - msg_body, dptime, - &msg_pdu_len); - if (msg_pdu) { - DBG("msg_pdu_len = %d", msg_pdu_len); - - g_string_append_printf(msg, LENGTH, msg_pdu_len); - g_string_append(msg, MSG_BODY_BEGIN); - for (j = 0; j < msg_pdu_len; j++) - g_string_append_printf(msg, "%02x", - msg_pdu[j]); - - g_string_append(msg, MSG_BODY_END); - g_free(msg_pdu); - } - } - } +static gboolean __bluetooth_map_start_service() +{ + FN_START; + gboolean sms; + gboolean email; - g_string_append(msg, END_BBODY); - g_string_append(msg, END_BENV); - g_string_append(msg, END_BMSEG); - g_free(folder_path); + sms = _bt_map_start_sms_service(); + email = _bt_map_start_email_service(); + if (sms && email) + return TRUE; FN_END; - return g_string_free(msg, FALSE); + return FALSE; } -static void __bt_message_info_free(struct message_info msg_info) +static gboolean __bt_validate_utf8(char **text) { FN_START; - g_free(msg_info.handle); - g_free(msg_info.subject); - g_free(msg_info.datetime); - g_free(msg_info.sender_name); - g_free(msg_info.sender_addressing); - g_free(msg_info.replyto_addressing); - g_free(msg_info.recipient_name); - g_free(msg_info.recipient_addressing); - g_free(msg_info.type); - g_free(msg_info.reception_status); - g_free(msg_info.size); - g_free(msg_info.attachment_size); + if (g_utf8_validate(*text, -1, NULL)) + return TRUE; + FN_END; + return FALSE; } -static struct message_info __bt_message_info_get(msg_struct_t msg_struct_handle) +gboolean _bt_validate_msg_data(message_info_t *msg_info) { FN_START; - struct message_info msg_info = {0,}; - int ret; - int msg_id; - guint64 uid; - int dptime; - int m_type = 0; - int data_size; - int priority; - int direction_type; - int count; - bool protect_status = 0; - bool read_status = 0; - - char msg_handle[BT_MAP_MSG_HANDLE_MAX] = {0,}; - char msg_datetime[BT_MAP_TIMESTAMP_MAX_LEN] = {0,}; - char msg_size[5] = {0,}; - char msg_body[BT_MAP_MSG_BODY_MAX] = {0,}; - char addr_value[MAX_ADDRESS_VAL_LEN] = {0,}; - char name_value[MAX_DISPLAY_NAME_LEN] = {0,}; - - msg_info.text = FALSE; - msg_info.protect = FALSE; - msg_info.read = FALSE; - msg_info.priority = FALSE; - - msg_struct_t msg = NULL; - msg_struct_t send_opt = NULL; - msg_list_handle_t addr_list = NULL; - msg_struct_t addr_info = NULL; - - ret = msg_get_int_value(msg_struct_handle, MSG_MESSAGE_ID_INT, &msg_id); - if (ret == MSG_SUCCESS) { - uid = __bt_add_id(msg_id); - snprintf(msg_handle, sizeof(msg_handle), "%llx", (long long unsigned int)uid); - } - msg_info.handle = g_strdup(msg_handle); - - msg = msg_create_struct(MSG_STRUCT_MESSAGE_INFO); - if (msg == NULL) - goto next; - - send_opt = msg_create_struct(MSG_STRUCT_SENDOPT); - if (send_opt == NULL) - goto next; - - ret = msg_get_message(g_msg_handle, - (msg_message_id_t)msg_id, - msg, send_opt); - if (ret != MSG_SUCCESS) { - DBG("ret = %d\n", ret); - goto next; - } - - ret = msg_get_list_handle(msg, MSG_MESSAGE_ADDR_LIST_HND, - (void **)&addr_list); - if (ret != MSG_SUCCESS) { - DBG("ret = %d\n", ret); - goto next; - } - - count = msg_list_length(addr_list); - - if (count != 0) { - addr_info = (msg_struct_t)msg_list_nth_data(addr_list, 0); + if (msg_info == NULL) + return FALSE; - ret = msg_get_str_value(addr_info, - MSG_ADDRESS_INFO_ADDRESS_VALUE_STR, - addr_value, MAX_ADDRESS_VAL_LEN); - if (ret == MSG_SUCCESS) - DBG_SECURE("addr_value %s\n", addr_value); + if (msg_info->subject) + return __bt_validate_utf8(&msg_info->subject); - ret = msg_get_str_value(addr_info, - MSG_ADDRESS_INFO_DISPLAYNAME_STR, - name_value, MAX_DISPLAY_NAME_LEN); + if (msg_info->sender_name) + return __bt_validate_utf8(&msg_info->sender_name); - if (ret == MSG_SUCCESS) - DBG_SECURE("name_value %s\n", name_value); + if (msg_info->sender_addressing) + return __bt_validate_utf8(&msg_info->sender_addressing); - if (!strlen(name_value)) - g_stpcpy(name_value, addr_value); + if (msg_info->replyto_addressing) + return __bt_validate_utf8(&msg_info->replyto_addressing); - DBG_SECURE("name_value %s\n", name_value); - } + if (msg_info->recipient_name) + return __bt_validate_utf8(&msg_info->recipient_name); - ret = msg_get_int_value(msg, MSG_MESSAGE_DIRECTION_INT, - &direction_type); - if (ret != MSG_SUCCESS) - goto next; + if (msg_info->recipient_addressing) + return __bt_validate_utf8(&msg_info->recipient_addressing); - if (direction_type == MSG_DIRECTION_TYPE_MT) { - msg_info.sender_name = g_strdup(name_value); - msg_info.sender_addressing = g_strdup(addr_value); - msg_info.recipient_name = g_strdup("Unknown"); - msg_info.recipient_addressing = g_strdup("0000"); - } else { - msg_info.sender_name = g_strdup("Unknown"); - msg_info.sender_addressing = g_strdup("0000"); - msg_info.recipient_name = g_strdup(name_value); - msg_info.recipient_addressing = g_strdup(addr_value); - } + FN_END; + return TRUE; +} -next: - msg_release_struct(&msg); - msg_release_struct(&send_opt); +static void __bt_mns_client_connect(char *address) +{ + FN_START; + GDBusConnection *connection; + GVariantBuilder builder; + GVariant *args; + GVariant *param; + GVariant *value; + GError *error = NULL; + const char *session_path; - ret = msg_get_int_value(msg_struct_handle, - MSG_MESSAGE_DISPLAY_TIME_INT, &dptime); - if (ret == MSG_SUCCESS) { - __get_msg_timestamp((time_t *)&dptime, msg_datetime); + if (g_mns_proxy) { + DBG_SECURE("MNS Client already connected to %s", address); + return; } - msg_info.datetime = g_strdup(msg_datetime); - ret = msg_get_int_value(msg_struct_handle, MSG_MESSAGE_TYPE_INT, - &m_type); - if (ret == MSG_SUCCESS) { - DBG("m_type %d\n", m_type); + connection = __bt_map_get_gdbus_connection(); + if (connection == NULL) { + DBG("Could not get GDBus Connection"); + return; } - msg_info.type = g_strdup("SMS_GSM"); + g_mns_proxy = g_dbus_proxy_new_sync(connection, + G_DBUS_PROXY_FLAGS_NONE, NULL, + OBEX_CLIENT_SERVICE, OBEX_CLIENT_PATH, + OBEX_CLIENT_INTERFACE, NULL, &error); - ret = msg_get_str_value(msg_struct_handle, - MSG_MESSAGE_SMS_DATA_STR, msg_body, - BT_MAP_MSG_BODY_MAX); - if (ret == MSG_SUCCESS) { - DBG_SECURE("SMS subject %s", msg_body); - if (strlen(msg_body)) { - msg_info.text = TRUE ; - msg_info.subject = __bt_get_truncated_utf8_string(msg_body); - } + if (!g_mns_proxy) { + ERR("Failed to get a proxy for D-Bus"); + return; } - ret = msg_get_int_value(msg_struct_handle, MSG_MESSAGE_DATA_SIZE_INT, - &data_size); - if (ret == MSG_SUCCESS) - snprintf(msg_size, sizeof(msg_size), "%d", data_size); - - msg_info.size = g_strdup(msg_size); + /* Create Hash*/ + g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY); + g_variant_builder_add(&builder, "{sv}", "Target", + g_variant_new("s", "MNS")); + args = g_variant_builder_end(&builder); - msg_info.reception_status = g_strdup("complete"); - msg_info.attachment_size = g_strdup("0"); + param = g_variant_new("(s@a{sv})", address, args); - ret = msg_get_bool_value(msg_struct_handle, MSG_MESSAGE_PROTECTED_BOOL, - &protect_status); - if (ret == MSG_SUCCESS) { - if (protect_status) - msg_info.protect = TRUE; - } + value = g_dbus_proxy_call_sync(g_mns_proxy, + "CreateSession", param, G_DBUS_CALL_FLAGS_NONE, -1, + NULL, &error); + if (value == NULL) { + /* dBUS-RPC is failed */ + ERR("dBUS-RPC is failed"); + if (error != NULL) { + /* dBUS gives error cause */ + ERR("D-Bus API failure: errCode[%x], message[%s]", + error->code, error->message); - ret = msg_get_bool_value(msg_struct_handle, MSG_MESSAGE_READ_BOOL, - &read_status); - if (ret == MSG_SUCCESS) { - if (read_status) - msg_info.read = TRUE; + g_clear_error(&error); + } + g_object_unref(g_mns_proxy); + g_mns_proxy = NULL; + return; } - ret = msg_get_int_value(msg_struct_handle, MSG_MESSAGE_PRIORITY_INT, - &priority); - if (ret == MSG_SUCCESS) { - if (priority == MSG_MESSAGE_PRIORITY_HIGH) - msg_info.priority = TRUE; - } + g_variant_get(value, "(&o)", &session_path); + g_mns_path = g_strdup(session_path); + DBG("g_mns_path = %s\n", g_mns_path); + g_variant_unref(value); FN_END; - return msg_info; } -static void __bluetooth_map_msg_incoming_status_cb(msg_handle_t handle, - msg_struct_t msg, - void *user_param) +static void __bt_mns_client_disconnect() { FN_START; - int msg_id = 0; - int msg_type = 0; - int ret; - - guint64 uid; + GError *error = NULL; + GVariant *value; if (!g_mns_proxy) { - INFO("MNS Client not connected"); + ERR("No proxy to disconnect"); return; } - ret = msg_get_int_value(msg, MSG_MESSAGE_TYPE_INT, &msg_type); - if (ret != MSG_SUCCESS) - return; + value = g_dbus_proxy_call_sync(g_mns_proxy, + "RemoveSession", g_variant_new("(o)", g_mns_path), + G_DBUS_CALL_FLAGS_NONE, -1, + NULL, &error); - if (msg_type != MSG_TYPE_SMS) { - INFO("Not a SMS"); + if (value == NULL) { + /* dBUS-RPC is failed */ + ERR("dBUS-RPC is failed: Could not remove MAP session"); + if (error != NULL) { + /* dBUS gives error cause */ + ERR("D-Bus API failure: errCode[%x], message[%s]", + error->code, error->message); + + g_clear_error(&error); + } return; } - ret = msg_get_int_value(msg, MSG_MESSAGE_ID_INT, &msg_id); - if (ret != MSG_SUCCESS) - return;; - - uid = __bt_add_id(msg_id); + g_free(g_mns_path); + g_mns_path = NULL; - __bt_mns_client_event_notify("NewMessage", uid, - "TELECOM/MSG/INBOX", "", - "SMS_GSM"); + g_object_unref(g_mns_proxy); + g_mns_proxy = NULL; + g_variant_unref(value); FN_END; - return; } -static void __bluetooth_map_msg_sent_status_cb(msg_handle_t handle, - msg_struct_t msg, - void *user_param) +void _bt_mns_client_event_notify(gchar *event, guint64 handle, + gchar *folder, gchar *old_folder, + gchar *msg_type) { FN_START; - int ret; - int status; + GError *error = NULL; + GDBusProxy *mns_proxy; + GDBusConnection *connection = NULL; + GVariant *value; if (!g_mns_proxy) { - INFO("MNS Client not connected"); + ERR("No client proxy"); return; } - ret = msg_get_int_value(msg, MSG_SENT_STATUS_NETWORK_STATUS_INT, - &status); - if (ret != MSG_SUCCESS) + connection = __bt_map_get_gdbus_connection(); + if (connection == NULL) { + DBG("Could not get GDBus Connection"); return; + } - if (status == MSG_NETWORK_SEND_SUCCESS) { - INFO("MSG SENT SUCCESS !!! "); - __bt_mns_client_event_notify("MessageShift", - current_push_map_id, - "TELECOM/MSG/SENT", - "TELECOM/MSG/OUTBOX", - "SMS_GSM"); - - __bt_mns_client_event_notify("SendingSuccess", - current_push_map_id, - "TELECOM/MSG/SENT", "", - "SMS_GSM"); - } else { - ERR("MSG SENT FAIL !!! [%d]", status); - __bt_mns_client_event_notify("SendingFailure", - current_push_map_id, - "TELECOM/MSG/OUTBOX", "", - "SMS_GSM"); + mns_proxy = g_dbus_proxy_new_sync(connection, + G_DBUS_PROXY_FLAGS_NONE, NULL, + OBEX_CLIENT_SERVICE, g_mns_path, + MNS_CLIENT_INTERFACE, NULL, &error); + if (mns_proxy == NULL) { + ERR("Failed to get a proxy for D-Bus\n"); + return; } - FN_END; - return; -} - -static gboolean __bluetooth_map_start_service() -{ - FN_START; - msg_error_t err; - - err = msg_open_msg_handle(&g_msg_handle); - if (err != MSG_SUCCESS) { - ERR("msg_open_msg_handle error = %d\n", err); - return FALSE; - } - - if (-1 == __bt_get_folder_id(BT_MAP_DELETED_FOLDER_NAME)) - __bt_add_deleted_folder(); - - err = msg_reg_sms_message_callback(g_msg_handle, - __bluetooth_map_msg_incoming_status_cb, - 0, (void *)BT_MAP_MSG_CB); - if (err != MSG_SUCCESS) { - ERR("msg_reg_sms_message_callback error = %d\n", err); - return FALSE; - } - - err = msg_reg_sent_status_callback(g_msg_handle, - __bluetooth_map_msg_sent_status_cb, - NULL); - if (err != MSG_SUCCESS) { - ERR("msg_reg_sent_status_callback error = %d\n", err); - return FALSE; - } - - FN_END; - return TRUE; -} - -static void __bluetooth_map_stop_service() -{ - FN_START; - msg_error_t err = MSG_SUCCESS; - int folder_id; - - folder_id = __bt_get_folder_id(BT_MAP_DELETED_FOLDER_NAME); - if (-1 != folder_id) { - err = msg_delete_folder(g_msg_handle, folder_id); - if (err != MSG_SUCCESS) - ERR("Delete folder failed"); - } - - if (NULL != g_msg_handle) - msg_close_msg_handle(&g_msg_handle); - - g_msg_handle = NULL; - - FN_END; - return; -} - -static gboolean __bt_validate_utf8(char **text) -{ - FN_START; - if (g_utf8_validate(*text, -1, NULL)) - return TRUE; - - FN_END; - return FALSE; -} - -static gboolean __bt_validate_msg_data(struct message_info *msg_info) -{ - FN_START; - if (msg_info == NULL) - return FALSE; - - if (msg_info->subject) - return __bt_validate_utf8(&msg_info->subject); - - if (msg_info->sender_name) - return __bt_validate_utf8(&msg_info->sender_name); - - if (msg_info->sender_addressing) - return __bt_validate_utf8(&msg_info->sender_addressing); - - if (msg_info->replyto_addressing) - return __bt_validate_utf8(&msg_info->replyto_addressing); - - if (msg_info->recipient_name) - return __bt_validate_utf8(&msg_info->recipient_name); - - if (msg_info->recipient_addressing) - return __bt_validate_utf8(&msg_info->recipient_addressing); - - FN_END; - return TRUE; -} - -msg_error_t __bt_send_sms(int msg_id, msg_struct_t p_msg, msg_struct_t p_send_opt) -{ - FN_START; - msg_error_t err; - msg_struct_t p_req; - - p_req = msg_create_struct(MSG_STRUCT_REQUEST_INFO); - - msg_set_int_value(p_msg, MSG_MESSAGE_ID_INT, msg_id); - msg_set_struct_handle(p_req, MSG_REQUEST_MESSAGE_HND, p_msg); - msg_set_struct_handle(p_req, MSG_REQUEST_SENDOPT_HND, p_send_opt); - - err = msg_sms_send_message(g_msg_handle, p_req); - if (err != MSG_SUCCESS) - ERR("Failed msg_sms_send_message %d", err); - - msg_release_struct(&p_req); - FN_END; - return err; -} - -static int __bt_push_sms(gboolean send, int folder_id, char *body, - GSList *recepients) -{ - FN_START; - msg_struct_t msg_info = NULL; - msg_struct_t send_opt = NULL; - msg_error_t err; - - int count = 0; - int i = 0; - int msg_id = -1; - - msg_info = msg_create_struct(MSG_STRUCT_MESSAGE_INFO); - if (msg_info == NULL) - goto fail; - - err = msg_set_int_value(msg_info, MSG_MESSAGE_TYPE_INT, MSG_TYPE_SMS); - if (err != MSG_SUCCESS) - goto fail; - - if (body) { - err = msg_set_str_value(msg_info, - MSG_MESSAGE_SMS_DATA_STR, - body, strlen(body)); - if (err != MSG_SUCCESS) - goto fail; - } else { - err = msg_set_str_value(msg_info, MSG_MESSAGE_SMS_DATA_STR, - NULL, 0); - if (err != MSG_SUCCESS) - goto fail; - } - - DBG("folder_id %d\n", folder_id); - err = msg_set_int_value(msg_info, MSG_MESSAGE_FOLDER_ID_INT, - folder_id); - if (err != MSG_SUCCESS) - goto fail; - - if (recepients) { - count = g_slist_length(recepients); - DBG("Count = %d\n", count); - - for (i = 0; i < count; i++) { - msg_struct_t tmp_addr; - char *address = (char *)g_slist_nth_data(recepients, i); - if (address == NULL) { - ERR("[ERROR] address is value NULL, skip"); - continue; - } - msg_list_add_item(msg_info, - MSG_MESSAGE_ADDR_LIST_HND, &tmp_addr); - - msg_set_int_value(tmp_addr, - MSG_ADDRESS_INFO_RECIPIENT_TYPE_INT, - MSG_RECIPIENTS_TYPE_TO); + value = g_dbus_proxy_call_sync(mns_proxy, "SendEvent", + g_variant_new("(stsss)", event, handle, folder, old_folder, msg_type), + G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); + if (value == NULL) { + /* dBUS-RPC is failed */ + ERR("dBUS-RPC is failed: SendEvent failed"); + if (error != NULL) { + /* dBUS gives error cause */ + ERR("D-Bus API failure: errCode[%x], message[%s]", + error->code, error->message); - msg_set_str_value(tmp_addr, - MSG_ADDRESS_INFO_ADDRESS_VALUE_STR, - address, strlen(address)); + g_clear_error(&error); } - } - - send_opt = msg_create_struct(MSG_STRUCT_SENDOPT); - - err = msg_set_bool_value(send_opt, MSG_SEND_OPT_SETTING_BOOL, true); - if (err != MSG_SUCCESS) - goto fail; - - /* Do not keep a copy */ - err = msg_set_bool_value(send_opt, MSG_SEND_OPT_KEEPCOPY_BOOL, - opt.save_copy); - if (err != MSG_SUCCESS) - goto fail; - - msg_id = msg_add_message(g_msg_handle, msg_info, send_opt); - DBG("msg_id = %d\n", msg_id); - - if (send == TRUE) - __bt_send_sms(msg_id, msg_info, send_opt); - - -fail: - msg_release_struct(&msg_info); - msg_release_struct(&send_opt); - FN_END; - return msg_id; -} - -static void __bt_mns_client_connect(char *address) -{ - FN_START; - GHashTable *hash; - GValue *tgt_value; - GError *error = NULL; - const char *session_path = NULL; - - if (g_mns_proxy) { - DBG_SECURE("MNS Client already connected to %s", address); - return; - } - - g_mns_proxy = dbus_g_proxy_new_for_name(g_connection, - OBEX_CLIENT_SERVICE, - OBEX_CLIENT_PATH, - OBEX_CLIENT_INTERFACE); - if (!g_mns_proxy) { - ERR("Failed to get a proxy for D-Bus\n"); - return; - } - - hash = g_hash_table_new_full(g_str_hash, g_str_equal, - NULL, (GDestroyNotify)g_free); - - tgt_value = g_new0(GValue, 1); - g_value_init(tgt_value, G_TYPE_STRING); - g_value_set_string(tgt_value, "MNS"); - g_hash_table_insert(hash, "Target", tgt_value); - - dbus_g_proxy_call(g_mns_proxy, "CreateSession", &error, - G_TYPE_STRING,address, - dbus_g_type_get_map("GHashTable", G_TYPE_STRING, G_TYPE_VALUE), - hash, G_TYPE_INVALID, - DBUS_TYPE_G_OBJECT_PATH, &session_path, - G_TYPE_INVALID); - if (error) { - ERR("Error [%s]", error->message); - g_error_free(error); - g_hash_table_destroy(hash); - g_object_unref(g_mns_proxy); - g_mns_proxy = NULL; + g_object_unref(mns_proxy); return; } - g_mns_path = g_strdup(session_path); - DBG("g_mns_path = %s\n", g_mns_path); - - g_hash_table_destroy(hash); - + g_variant_unref(value); + g_object_unref(mns_proxy); FN_END; - return; } -static void __bt_mns_client_disconnect() +static gchar *__bt_get_map_folder(int folder) { - FN_START; - GError *error = NULL; - - if (!g_mns_proxy) { - ERR("No proxy to disconnect"); - return; - } - - dbus_g_proxy_call(g_mns_proxy, "RemoveSession", &error, - DBUS_TYPE_G_OBJECT_PATH, g_mns_path, - G_TYPE_INVALID, G_TYPE_INVALID); - if (error) { - ERR("Error [%s]", error->message); - g_error_free(error); - } - - g_free(g_mns_path); - g_mns_path = NULL; - - g_object_unref(g_mns_proxy); - g_mns_proxy = NULL; - - FN_END; - return; + switch (folder) { + case BT_MSG_INBOX: + return g_strdup("INBOX"); + case BT_MSG_SENT: + return g_strdup("SENT"); + case BT_MSG_OUTBOX: + return g_strdup("OUTBOX"); + case BT_MSG_DRAFT: + return g_strdup("DRAFT"); + case BT_MSG_DELETED: + return g_strdup("DELETED"); + } + return NULL; } -static void __bt_mns_client_event_notify(gchar *event, guint64 handle, - gchar *folder, gchar *old_folder, - gchar *msg_type) +static GList *_bt_map_merge_sorted(GSList *sms_list, GSList *email_list) { - FN_START; - GError *error = NULL; - DBusGProxy *mns_proxy; - - if (!g_mns_proxy) { - ERR("No client proxy"); - return; + GList *list = NULL; + message_info_t *sms; + message_info_t *email; + +/* **********************Note from glib documentation************************** + * g_list_append() has to traverse the entire list to find the end, which + * is inefficient when adding multiple elements. A common idiom to avoid the + * inefficiency is to use g_list_prepend() and reverse the list with + * g_list_reverse() when all elements have been added. + * ***************************************************************************/ + + while (sms_list && email_list) { + sms = sms_list->data; + email = email_list->data; + + if (sms->time > email->time) { + list = g_list_prepend(list, sms); + sms_list = g_slist_next(sms_list); + } else { + list = g_list_prepend(list, email); + email_list = g_slist_next(email_list); + } } - mns_proxy = dbus_g_proxy_new_for_name(g_connection, - OBEX_CLIENT_SERVICE, - g_mns_path, - MNS_CLIENT_INTERFACE); - if (mns_proxy == NULL) { - ERR("Failed to get a proxy for D-Bus\n"); - return; + while (sms_list) { + sms = sms_list->data; + list = g_list_prepend(list, sms); + sms_list = g_slist_next(sms_list); } - - dbus_g_proxy_call(mns_proxy, "SendEvent", &error, - G_TYPE_STRING, event, - G_TYPE_UINT64, handle, - G_TYPE_STRING, folder, - G_TYPE_STRING, old_folder, - G_TYPE_STRING, msg_type, - G_TYPE_INVALID, G_TYPE_INVALID); - if (error) { - ERR("Error [%s]", error->message); - g_error_free(error); + while (email_list) { + email = email_list->data; + list = g_list_prepend(list, email); + email_list = g_slist_next(email_list); } - g_object_unref(mns_proxy); - FN_END; + list = g_list_reverse(list); + return list; } -static gboolean bluetooth_map_get_folder_tree(BluetoothMapAgent *agent, - DBusGMethodInvocation *context) +static GVariant *__bt_map_get_folder_tree(GError **err) { - FN_START; - GPtrArray *array = g_ptr_array_new(); - GValue value; - GError *error = NULL; - - char name[BT_MAP_MSG_INFO_MAX] = {0,}; - char folder_name[BT_MAP_MSG_INFO_MAX] = {0,}; + GVariant *folder_list = NULL; + GVariantBuilder *builder = g_variant_builder_new(G_VARIANT_TYPE("a(s)")); int i; - int ret; - gboolean msg_ret = TRUE; - - msg_struct_list_s folder_list = {0,}; - msg_struct_t p_folder; - - if (g_msg_handle == NULL) { - msg_ret = FALSE; - goto done; - } - - if (msg_get_folder_list(g_msg_handle, &folder_list) != MSG_SUCCESS) { - msg_ret = FALSE; - goto done; - } + gboolean sms_ret = TRUE; + gboolean email_ret = TRUE; - for (i = 0; i < folder_list.nCount; i++) { - p_folder = folder_list.msg_struct_info[i]; - memset(folder_name, 0x00, BT_MAP_MSG_INFO_MAX); + sms_ret = _bt_map_sms_get_supported_folders(folders_supported); + email_ret = _bt_map_email_get_supported_folders(folders_supported); - ret = msg_get_str_value(p_folder, MSG_FOLDER_INFO_NAME_STR, - folder_name, BT_MAP_MSG_INFO_MAX); - if (ret != MSG_SUCCESS) - continue; - - if (g_strstr_len(folder_name, -1, BT_MAP_MSG_TEMPLATE)) - continue; - - if (!g_ascii_strncasecmp(folder_name, BT_MAP_SENT_FOLDER_NAME, - strlen(BT_MAP_SENT_FOLDER_NAME))) { - memset(folder_name, 0, sizeof(folder_name)); - g_strlcpy(folder_name, BT_MAP_SENT_FOLDER_NAME, - sizeof(folder_name)); + if (sms_ret || email_ret) { + for (i = 0; i < 5; i++) { + if (folders_supported[i][BT_MSG_SOURCE_SMS] || + folders_supported[i][BT_MSG_SOURCE_EMAIL]) { + g_variant_builder_add(builder, "(s)", __bt_get_map_folder(i)); + } } - g_strlcpy(name, folder_name, sizeof(name)); - memset(&value, 0, sizeof(GValue)); - g_value_init(&value, DBUS_STRUCT_STRING_STRING_UINT); - g_value_take_boxed(&value, dbus_g_type_specialized_construct( - DBUS_STRUCT_STRING_STRING_UINT)); - dbus_g_type_struct_set(&value, 0, name, G_MAXUINT); - g_ptr_array_add(array, g_value_get_boxed(&value)); - } - -done: - - if (folder_list.msg_struct_info) - msg_release_list_struct(&folder_list); - - if (msg_ret == FALSE) { - g_ptr_array_free(array, TRUE); - - error = __bt_map_agent_error(BT_MAP_AGENT_ERROR_INTERNAL, - "InternalError"); - dbus_g_method_return_error(context, error); - g_error_free(error); - return FALSE; + folder_list = g_variant_new("(a(s))", builder); } else { - dbus_g_method_return(context, array); - g_ptr_array_free(array, TRUE); - FN_END; - return TRUE; + *err = __bt_map_error(BT_MAP_AGENT_ERROR_INTERNAL, + "InternalError"); } + + g_variant_builder_unref(builder); + return folder_list; } -static gboolean bluetooth_map_get_message_list(BluetoothMapAgent *agent, - gchar *folder_name, guint16 max, - DBusGMethodInvocation *context) +static GVariant *__bt_map_get_message_list(char *folder_name, guint16 max, + guint16 offset, guint8 subject_len, + map_msg_filter_t *filter, GError **err) { FN_START; - GPtrArray *array = g_ptr_array_new(); - GValue value; - GError *error = NULL; - - char *folder = NULL; - int i = 0; - int ret = 0; - int folder_id = -1; - int folder_len; - bool read; + GVariant *message_list = NULL; + GVariantBuilder *builder = g_variant_builder_new(G_VARIANT_TYPE("a(ssssssssssbsbbbbs)")); + GSList *sms_list = NULL; + GSList *email_list = NULL; + gboolean sms_ret = TRUE; + gboolean email_ret = TRUE; guint64 count = 0; + guint64 count_sms = 0; + guint64 count_email = 0; gboolean newmsg = FALSE; + char *folder = NULL; - msg_struct_list_s folder_list = {0,}; - msg_struct_list_s msg_list = {0,}; - msg_struct_t list_cond; - - if (g_msg_handle == NULL) - goto fail; - + DBG("Folder:%s Max:%d", folder_name, max); if (!folder_name) goto fail; - folder_len = strlen(folder_name); /* In case of parent folders send empty message listing */ - if (!g_ascii_strncasecmp(folder_name, "/", folder_len) || - !g_ascii_strncasecmp(folder_name, "/telecom", folder_len) || - !g_ascii_strncasecmp(folder_name, "/telecom/msg", folder_len)) - goto done; + /* + if (g_ascii_strncasecmp(folder_name, "/telecom/msg/", strlen("/telecom/msg/"))) + goto fail; + */ folder = strrchr(folder_name, '/'); if (NULL == folder) folder = folder_name; else folder++; - - ret = msg_get_folder_list(g_msg_handle, &folder_list); - if (ret != MSG_SUCCESS) - goto fail; - - for (i = 0; i < folder_list.nCount; i++) { - char f_name[BT_MAP_MSG_INFO_MAX] = {0, }; - msg_struct_t p_folder = folder_list.msg_struct_info[i]; - - ret = msg_get_str_value(p_folder, MSG_FOLDER_INFO_NAME_STR, - f_name, BT_MAP_MSG_INFO_MAX); - if (ret != MSG_SUCCESS) - continue; - - if (!g_ascii_strncasecmp(f_name, folder, strlen(folder))) { - ret = msg_get_int_value(p_folder, MSG_FOLDER_INFO_ID_INT, - &folder_id); - if (ret != MSG_SUCCESS) - goto fail; - - DBG("folder_id %d \n", folder_id); - - break; + DBG("Filter Type: %d", filter->type); + if ((filter->type & FILTER_TYPE_SMS_GSM) == 0) { /* Check if SMS is requested */ + if (!g_ascii_strncasecmp(folder, "SENT", strlen("SENT"))) { + /* Failed Sent SMS are stored in OUTBOX. + * Hence, Fetch both SENT and OUTBOX */ + gboolean sent_ret = _bt_map_get_sms_message_list("SENT", + max + offset, subject_len, filter, + &sms_list, &count_sms, &newmsg); + gboolean outbox_ret = _bt_map_get_sms_message_list("OUTBOX", + max + offset, subject_len, filter, + &sms_list, &count_sms, &newmsg); + sms_ret = (sent_ret || outbox_ret); + } else { + sms_ret = _bt_map_get_sms_message_list(folder, + max + offset, subject_len, filter, + &sms_list, &count_sms, &newmsg); } } - if (folder_id == -1) - goto fail; - - list_cond = msg_create_struct(MSG_STRUCT_MSG_LIST_CONDITION); - ret = msg_set_int_value(list_cond, - MSG_LIST_CONDITION_FOLDER_ID_INT, - folder_id); - if (ret != MSG_SUCCESS) - goto fail; - - ret = msg_set_int_value(list_cond, - MSG_LIST_CONDITION_MSGTYPE_INT, MSG_TYPE_SMS); - if (ret != MSG_SUCCESS) - goto fail; - - ret = msg_get_message_list2(g_msg_handle, list_cond, &msg_list); - - msg_release_struct(&list_cond); - - if (ret != MSG_SUCCESS) - goto fail; - - count = (guint64)msg_list.nCount; - - for (i = 0; i < count; i++) { - msg_get_bool_value(msg_list.msg_struct_info[i], - MSG_MESSAGE_READ_BOOL, &read); - if (read == false) { - newmsg = TRUE; - break; + if ((filter->type & FILTER_TYPE_EMAIL) == 0) { /* Check if EMAIL is requested */ + email_ret = _bt_map_get_email_list(folder, + max + offset, subject_len, filter, + &email_list, &count_email, &newmsg); + } + + if (sms_ret || email_ret) { + GList *list = _bt_map_merge_sorted(sms_list, email_list); + GList *pos = NULL; + int i; + message_info_t *msg_info = NULL; + + g_slist_free(sms_list); + g_slist_free(email_list); + + count = count_sms + count_email; + + pos = g_list_nth(list, offset); + for (i = offset; pos && i < max + offset; i++) { + msg_info = pos->data; + g_variant_builder_add(builder, "(ssssssssssbsbbbbs)", + msg_info->handle, + msg_info->subject, + msg_info->datetime, + msg_info->sender_name, + msg_info->sender_addressing, + msg_info->recipient_name, + msg_info->recipient_addressing, + msg_info->type, + msg_info->size, + msg_info->reception_status, + msg_info->text, + msg_info->attachment_size, + msg_info->priority, + msg_info->read, + msg_info->sent, + msg_info->protect, + msg_info->replyto_addressing); + + pos = g_list_next(pos); } - } - - DBG("count = %llx, newmsg = %d, max = %d", count, newmsg, max); - - if (max == 0) - goto done; - - for (i = 0; i < msg_list.nCount; i++) { - - struct message_info msg_info; - memset(&value, 0, sizeof(GValue)); - g_value_init(&value, DBUS_STRUCT_MESSAGE_LIST); - g_value_take_boxed(&value, dbus_g_type_specialized_construct( - DBUS_STRUCT_MESSAGE_LIST)); + message_list = g_variant_new("(bta(ssssssssssbsbbbbs))", + newmsg, count, builder); + g_variant_builder_unref(builder); + g_list_free_full(list, _bt_message_info_free); - msg_info = __bt_message_info_get(msg_list.msg_struct_info[i]); - - if (!__bt_validate_msg_data(&msg_info)) { - __bt_message_info_free(msg_info); - count--; - continue; - } - - dbus_g_type_struct_set(&value, 0, msg_info.handle, - 1, msg_info.subject, - 2, msg_info.datetime, - 3, msg_info.sender_name, - 4, msg_info.sender_addressing, - 5, msg_info.recipient_name, - 6, msg_info.recipient_addressing, - 7, msg_info.type, - 8, msg_info.size, - 9, msg_info.reception_status, - 10, msg_info.text, - 11, msg_info.attachment_size, - 12, msg_info.priority, - 13, msg_info.read, - 14, msg_info.sent, - 15, msg_info.protect, - 16, msg_info.replyto_addressing, - G_MAXUINT); - g_ptr_array_add(array, g_value_get_boxed(&value)); - - __bt_message_info_free(msg_info); + return message_list; } -done: - if (folder_list.msg_struct_info) - ret = msg_release_list_struct(&folder_list); - - if (msg_list.msg_struct_info) - ret = msg_release_list_struct(&msg_list); - - dbus_g_method_return(context, newmsg, count, array); - g_ptr_array_free(array, TRUE); - FN_END; - return TRUE; - fail: - if (folder_list.msg_struct_info) - ret = msg_release_list_struct(&folder_list); - - if (msg_list.msg_struct_info) - ret = msg_release_list_struct(&msg_list); - - g_ptr_array_free(array, TRUE); - error = __bt_map_agent_error(BT_MAP_AGENT_ERROR_INTERNAL, - "InternalError"); - dbus_g_method_return_error(context, error); - g_error_free(error); + *err = __bt_map_error(BT_MAP_AGENT_ERROR_INTERNAL, + "InternalError"); + g_variant_builder_unref(builder); ERR("fail -"); - return FALSE; + return NULL; } -static gboolean bluetooth_map_get_message(BluetoothMapAgent *agent, - gchar *message_name, - gboolean attach, - gboolean transcode, - gboolean first_request, - DBusGMethodInvocation *context) +static GVariant *__bt_map_get_message(char *message_name, gboolean attach, + gboolean transcode, gboolean first_request, GError **err) { FN_START; - char *buf = NULL; + GVariant *message = NULL; int message_id = 0; + gboolean val_ret; + gchar *bmseg = NULL; - GError *error = NULL; - - msg_error_t msg_err; - msg_struct_t msg = NULL; - msg_struct_t send_opt = NULL; - - message_id = __bt_get_uid(message_name); - if (message_id == -1) - goto fail; - - DBG("message_id %d \n", message_id); - DBG("attach %d \n", attach); - DBG("transcode %d \n", transcode); - DBG("first_request %d \n", first_request); - - if (g_msg_handle == NULL) - goto fail; - - msg = msg_create_struct(MSG_STRUCT_MESSAGE_INFO); - if (!msg) - goto fail; - - send_opt = msg_create_struct(MSG_STRUCT_SENDOPT); - if (!send_opt) - goto fail; - - msg_err = msg_get_message(g_msg_handle, - (msg_message_id_t)message_id, - msg, send_opt); - if (msg_err != MSG_SUCCESS) - goto fail; - - buf = __bt_prepare_msg_bmseg(msg, attach, transcode); - - dbus_g_method_return(context, FALSE, buf); - msg_release_struct(&msg); - msg_release_struct(&send_opt); - g_free(buf); - - FN_END; - return TRUE; - -fail: + struct id_info *handle_info = __bt_get_uid(message_name); + if (handle_info == NULL) + return FALSE; - if (msg) - msg_release_struct(&msg); + message_id = handle_info->uid; + if (handle_info->msg_type == BT_MAP_ID_SMS) + val_ret = _bt_map_get_sms_message(message_id, attach, transcode, first_request, &bmseg); + else + val_ret = _bt_map_get_email_message(message_id, attach, transcode, first_request, &bmseg); - if (send_opt) - msg_release_struct(&send_opt); + if (val_ret) { + message = g_variant_new("(bs)", FALSE, bmseg); + g_free(bmseg); + FN_END; + return message; + } - error = __bt_map_agent_error(BT_MAP_AGENT_ERROR_INTERNAL, + *err = __bt_map_error(BT_MAP_AGENT_ERROR_INTERNAL, "InternalError"); - dbus_g_method_return_error(context, error); - g_error_free(error); ERR("fail - \n"); - return FALSE; + return NULL; } -static gboolean bluetooth_map_push_message(BluetoothMapAgent *agent, - gboolean save_copy, - gboolean retry_send, - gboolean native, - gchar *folder_name, - DBusGMethodInvocation *context) +static GVariant *__bt_map_push_message(gboolean save_copy, gboolean retry_send, + gboolean native, char *folder_name, GError **err) { FN_START; guint64 handle = 0; DBG_SECURE("folder_name = %s\n", folder_name); - handle = __bt_add_id(-1); + handle = _bt_add_id(-1, BT_MAP_ID_SMS); current_push_map_id = handle; + push_folder = g_strdup(folder_name); /* FALSE : Keep messages in Sent folder */ /* TRUE : don't keep messages in sent folder */ @@ -1879,222 +1350,106 @@ static gboolean bluetooth_map_push_message(BluetoothMapAgent *agent, opt.native = native; DBG("opt.native = %d\n", opt.native); - dbus_g_method_return(context, handle); + return g_variant_new("(t)", handle); FN_END; - return TRUE; } -static gboolean bluetooth_map_push_message_data(BluetoothMapAgent *agent, - gchar *bmsg, - DBusGMethodInvocation *context) +static GVariant *__bt_map_push_message_data(char *bmseg, GError **err) { FN_START; - int id = -1; - int folder_id; - char *body = NULL; - GSList *recepients = NULL; - gboolean send = FALSE; + gboolean ret = FALSE; - GError *error = NULL; - - INFO("BMSG is \n %s", bmsg); + DBG_SECURE("BMSG: %s", bmseg); struct bmsg_data *bmsg_info = NULL; - bmsg_info = bmsg_parse(bmsg); - if (!bmsg_info) - goto done; - - folder_id = __bt_get_folder_id(bmsg_info->folder); - if (folder_id == -1) - goto done; + bmsg_info = bmsg_parse(bmseg); + if (bmsg_info) { + if (!g_ascii_strcasecmp(bmsg_info->type, "SMS_GSM")) + ret = _bt_map_push_sms_data(bmsg_info, &opt, push_folder); + else if (!g_ascii_strcasecmp(bmsg_info->type, "EMAIL")) + ret = _bt_map_push_email_data(bmsg_info, &opt, push_folder); - if (MSG_OUTBOX_ID == folder_id) - send = TRUE; - - body = bmsg_get_msg_body(bmsg_info, opt.native); - if (body == NULL) - goto done; - - recepients = bmsg_get_msg_recepients(bmsg_info); - - id = __bt_push_sms(send, folder_id, body, recepients); - if (id == -1) - goto done; - - __bt_update_id(current_push_map_id, id); - -done: - g_free(body); - g_slist_free(recepients); - bmsg_free_bmsg(bmsg_info); + bmsg_free_bmsg(bmsg_info); + } - if (id == -1) { - error = __bt_map_agent_error(BT_MAP_AGENT_ERROR_INTERNAL, - "InternalError"); - dbus_g_method_return_error(context, error); - g_error_free(error); - FN_END; - return FALSE; + g_free(push_folder); + push_folder = NULL; + if (ret) { + INFO("Message Successfully Sent or Saved"); + return NULL; } - dbus_g_method_return(context); - FN_END; - return TRUE; + *err = __bt_map_error(BT_MAP_AGENT_ERROR_INTERNAL, + "InternalError"); + ERR("Error in sending or saving Message"); + return NULL; } -static gboolean bluetooth_map_update_message(BluetoothMapAgent *agent, - DBusGMethodInvocation *context) +/* Dummy Implementation */ +static GVariant *__bt_map_update_message(GError **err) { - int err = TRUE; - - dbus_g_method_return(context, err); - return TRUE; + return g_variant_new("(b)", TRUE); } -static gboolean bluetooth_map_set_read_status(BluetoothMapAgent *agent, - gchar *handle, - gboolean read_status, - DBusGMethodInvocation *context) +static GVariant *__bt_map_set_read_status(char *handle, gboolean read_status, GError **err) { FN_START; int msg_id; - GError *error = NULL; - msg_error_t msg_err; + gboolean val_ret; - msg_id = __bt_get_uid(handle); - if (msg_id == -1) + struct id_info *handle_info = __bt_get_uid(handle); + if (handle_info == NULL) goto fail; + msg_id = handle_info->uid; DBG("msg_id = %d, read_status = %d\n", msg_id, read_status); + if (handle_info->msg_type == BT_MAP_ID_SMS) + val_ret = _bt_map_sms_set_read_status(msg_id, read_status); + else + val_ret = _bt_map_set_email_read_status(msg_id, read_status); - msg_err = msg_update_read_status(g_msg_handle, msg_id, - read_status); - if (msg_err != MSG_SUCCESS) - goto fail; - - dbus_g_method_return(context); - FN_END; - return TRUE; + if (val_ret) { + FN_END; + return NULL; + } fail: - error = __bt_map_agent_error(BT_MAP_AGENT_ERROR_INTERNAL, + *err = __bt_map_error(BT_MAP_AGENT_ERROR_INTERNAL, "InternalError"); - dbus_g_method_return_error(context, error); - g_error_free(error); - ERR("fail -\n"); - return FALSE; + return NULL; } -static gboolean bluetooth_map_set_delete_status(BluetoothMapAgent *agent, - gchar *handle, - gboolean delete_status, - DBusGMethodInvocation *context) +static GVariant *__bt_map_set_delete_status(char *handle, gboolean delete_status, GError **err) { FN_START; int msg_id = 0; - int folder_id; - int del_folder_id; - gchar *folder_name = NULL; - guint64 map_id; - GError *error = NULL; - msg_error_t err; - msg_struct_t msg = NULL; - msg_struct_t send_opt = NULL; - - msg_id = __bt_get_uid(handle); - if (msg_id == -1) - goto fail; - - if (g_msg_handle == NULL) - goto fail; - - msg = msg_create_struct(MSG_STRUCT_MESSAGE_INFO); - if (msg == NULL) - goto fail; - - send_opt = msg_create_struct(MSG_STRUCT_SENDOPT); - if (send_opt == NULL) - goto fail; - - err = msg_get_message(g_msg_handle, - (msg_message_id_t)msg_id, - msg, send_opt); - if (err != MSG_SUCCESS) - goto fail; + gboolean val_ret; - err = msg_get_int_value(msg, MSG_MESSAGE_FOLDER_ID_INT, - &folder_id); - if (err != MSG_SUCCESS) + struct id_info *handle_info = __bt_get_uid(handle); + if (handle_info == NULL) goto fail; - folder_name = __bt_get_folder_name(folder_id); - del_folder_id = __bt_get_folder_id(BT_MAP_DELETED_FOLDER_NAME); - map_id = __bt_validate_uid(msg_id); - - DBG("msg_id = %d, delete_status = %d\n", msg_id, delete_status); - - if (-1 == del_folder_id) { - ERR("Delete folder not present"); - if (delete_status == TRUE) { - err = msg_delete_message(g_msg_handle, msg_id); - if (err != MSG_SUCCESS) - goto fail; - } - - } else { - if (delete_status == TRUE) { - err = msg_move_msg_to_folder(g_msg_handle, msg_id, del_folder_id); - if (err == MSG_SUCCESS) { - __bt_mns_client_event_notify("MessageShift", - map_id, - "TELECOM/MSG/DELETED", - folder_name, - "SMS_GSM"); - } - } else { - if (folder_id != del_folder_id) { - DBG("Message not in delete folder"); - goto fail; - } + msg_id = handle_info->uid; + if (handle_info->msg_type == BT_MAP_ID_SMS) + val_ret = _bt_map_set_sms_delete_status(msg_id, delete_status); + else + val_ret = _bt_map_set_email_delete_status(msg_id, delete_status); - err = msg_move_msg_to_folder(g_msg_handle, msg_id, MSG_INBOX_ID); - if (err == MSG_SUCCESS) { - __bt_mns_client_event_notify("MessageShift", - map_id, - "TELECOM/MSG/INBOX", - "TELECOM/MSG/DELETED", - "SMS_GSM"); - } - } + if (val_ret) { + FN_END; + return NULL; } - g_free(folder_name); - msg_release_struct(&msg); - msg_release_struct(&send_opt); - dbus_g_method_return(context); - FN_END; - return TRUE; - fail: - g_free(folder_name); - - msg_release_struct(&msg); - msg_release_struct(&send_opt); - - error = __bt_map_agent_error(BT_MAP_AGENT_ERROR_INTERNAL, + *err = __bt_map_error(BT_MAP_AGENT_ERROR_INTERNAL, "InternalError"); - dbus_g_method_return_error(context, error); - g_error_free(error); ERR("fail -\n"); - return FALSE; + return NULL; } -static gboolean bluetooth_map_noti_registration(BluetoothMapAgent *agent, - gchar *remote_addr, - gboolean status, - DBusGMethodInvocation *context) +static void __bt_map_noti_registration(char *remote_addr, gboolean status) { FN_START; DBG_SECURE("remote_addr = %s \n", remote_addr); @@ -2103,28 +1458,80 @@ static gboolean bluetooth_map_noti_registration(BluetoothMapAgent *agent, __bt_mns_client_connect(remote_addr); else __bt_mns_client_disconnect(); - - return TRUE; } -static gboolean bluetooth_map_destroy_agent(BluetoothMapAgent *agent, - DBusGMethodInvocation *context) +static void __bt_map_destroy_agent(void) { - FN_START; g_main_loop_quit(g_mainloop); +} + +static GDBusNodeInfo *__bt_map_create_method_node_info + (const gchar *introspection_data) +{ + GError *err = NULL; + GDBusNodeInfo *node_info = NULL; + + if (introspection_data == NULL) + return NULL; + + node_info = g_dbus_node_info_new_for_xml(introspection_data, &err); + + if (err) { + ERR("Unable to create node: %s", err->message); + g_clear_error(&err); + } + return node_info; +} + +static gboolean __bt_map_dbus_init(void) +{ + guint owner_id; + guint map_id; + GDBusNodeInfo *node_info; + GError *error = NULL; + GDBusConnection *gdbus_conn = __bt_map_get_gdbus_connection(); + + if (gdbus_conn == NULL) { + ERR("Error in creating the gdbus connection"); + return FALSE; + } + + owner_id = g_bus_own_name(G_BUS_TYPE_SESSION, + BT_MAP_SERVICE_NAME, + G_BUS_NAME_OWNER_FLAGS_NONE, + NULL, NULL, NULL, + NULL, NULL); + DBG("owner_id is [%d]", owner_id); + + node_info = __bt_map_create_method_node_info( + map_agent_introspection_xml); + if (node_info == NULL) + return FALSE; + + map_id = g_dbus_connection_register_object(gdbus_conn, BT_MAP_SERVICE_OBJECT_PATH, + node_info->interfaces[0], + &method_table, + NULL, NULL, &error); + + g_dbus_node_info_unref(node_info); + + if (map_id == 0) { + ERR("Failed to register: %s", error->message); + g_error_free(error); + return FALSE; + } + return TRUE; } int main(void) { FN_START; - BluetoothMapAgent *bluetooth_map_obj = NULL; - DBusGProxy *bus_proxy = NULL; - guint result = 0; int ret; - GError *error = NULL; DBG("Starting Bluetooth MAP agent"); + //g_type_init(); + g_mainloop = g_main_loop_new(NULL, FALSE); if (g_mainloop == NULL) { @@ -2132,47 +1539,8 @@ int main(void) return EXIT_FAILURE; } - g_connection = dbus_g_bus_get(DBUS_BUS_SESSION, &error); - - if (error != NULL) { - ERR("Couldn't connect to system bus[%s]\n", error->message); - g_error_free(error); - return EXIT_FAILURE; - } - - bus_proxy = dbus_g_proxy_new_for_name(g_connection, DBUS_SERVICE_DBUS, - DBUS_PATH_DBUS, - DBUS_INTERFACE_DBUS); - if (bus_proxy == NULL) { - ERR("Failed to get a proxy for D-Bus\n"); + if (__bt_map_dbus_init() == FALSE) goto failure; - } - - if (!dbus_g_proxy_call(bus_proxy, "RequestName", &error, G_TYPE_STRING, - BT_MAP_SERVICE_NAME, G_TYPE_UINT, 0, - G_TYPE_INVALID, G_TYPE_UINT, &result, - G_TYPE_INVALID)) { - if (error != NULL) { - ERR("RequestName RPC failed[%s]\n", error->message); - g_error_free(error); - } - goto failure; - } - - if (result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) { - ERR("Failed to get the primary well-known name.\n"); - goto failure; - } - - g_object_unref(bus_proxy); - bus_proxy = NULL; - - bluetooth_map_obj = g_object_new(BLUETOOTH_MAP_TYPE_AGENT, NULL); - - /* Registering it on the D-Bus */ - dbus_g_connection_register_g_object(g_connection, - BT_MAP_SERVICE_OBJECT_PATH, - G_OBJECT(bluetooth_map_obj)); if (__bluetooth_map_start_service() == FALSE) goto failure; @@ -2198,14 +1566,12 @@ int main(void) __bt_mns_client_disconnect(); - if (bus_proxy) - g_object_unref(bus_proxy); - if (bluetooth_map_obj) - g_object_unref(bluetooth_map_obj); - if (g_connection) - dbus_g_connection_unref(g_connection); + if (map_dbus_conn) + g_object_unref(map_dbus_conn); + + _bt_map_stop_sms_service(); + _bt_map_stop_email_service(); - __bluetooth_map_stop_service(); DBG("Bluetooth MAP agent Terminated successfully\n"); FN_END; return EXIT_FAILURE; diff --git a/map-agent/bluetooth_map_agent.h b/map-agent/bluetooth_map_agent.h index 14597f9..fcaad44 100644 --- a/map-agent/bluetooth_map_agent.h +++ b/map-agent/bluetooth_map_agent.h @@ -26,12 +26,9 @@ #include #include - #include - -#include - -#define BT_MAP_AGENT_ERROR (__bt_map_agent_error_quark()) +#include +#include "bluetooth_map_types.h" typedef enum { BT_MAP_AGENT_ERROR_INTERNAL, @@ -68,4 +65,21 @@ typedef enum { } \ } while (0) +void _bt_mns_client_event_notify(gchar *event, guint64 handle, + gchar *folder, gchar *old_folder, + gchar *msg_type); +int _bt_update_id(guint64 map_id, int new_uid, int msg_type); +gboolean _bt_validate_msg_data(message_info_t *msg_info); +void _bt_message_info_free(gpointer data); +void _get_msg_timestamp(time_t *ltime, char *timestamp); +guint64 _bt_add_id(int uid, int msg_type); +guint64 _bt_validate_uid(int uid, int msg_type); +gboolean is_mns_connected(void); +gchar *__bt_get_sms_pdu_from_msg_data(gchar *number, char *msg, time_t tm, + int *msg_pdu_len); +gboolean _bt_verify_read_status(message_info_t *msg_info, guint8 read_status); +gboolean _bt_verify_sender(message_info_t *msg_info, char *sender); +gboolean _bt_verify_receiver(message_info_t *msg_info, char *receiver); +gboolean _bt_verify_time(message_info_t *msg_info, map_msg_filter_t *filter); +gboolean _bt_filter_priority(message_info_t *msg_info, guint8 priority); #endif /* __DEF_BT_AGENT_H_ */ diff --git a/map-agent/bluetooth_map_agent.xml b/map-agent/bluetooth_map_agent.xml index 977418b..e69de29 100644 --- a/map-agent/bluetooth_map_agent.xml +++ b/map-agent/bluetooth_map_agent.xml @@ -1,63 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/map-agent/bluetooth_map_email.c b/map-agent/bluetooth_map_email.c new file mode 100644 index 0000000..e5210f0 --- /dev/null +++ b/map-agent/bluetooth_map_email.c @@ -0,0 +1,1072 @@ +/* + * Bluetooth-agent + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Hocheol Seo + * Syam Sidhardhan + * Chanyeol Park + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "email-types.h" +#include "email-api-init.h" +#include "email-api-account.h" +#include "email-api-mailbox.h" +#include "email-api-mail.h" +#include "email-api-network.h" +#include + +#include +#include + +#include +#include +#include + +#define BT_MAIL_ID_MAX_LENGTH 50 +#define BT_MAP_TIMESTAMP_MAX_LEN 16 +#define BT_MAIL_TEMP_BODY "/tmp/bt_mail.txt" +#define BT_MAP_MSG_HANDLE_MAX 21 +#define BT_EMAIL_STORAGE_INTERFACE "User.Email.StorageChange" +#define BT_EMAIL_STORAGE_PATH "/User/Email/StorageChange" +#define BT_EMAIL_STORAGE_SIGNAL "email" + +#define BEGIN_BMSEG "BEGIN:BMSG\r\n" +#define END_BMSEG "END:BMSG\r\n" +#define BMSEG_VERSION "VERSION:1.0\r\n" +#define MSEG_STATUS "STATUS:%s\r\n" +#define MSEG_TYPE "TYPE:%s\r\n" +#define FOLDER_PATH "FOLDER:%s\r\n" +#define EMAIL_VCARD "BEGIN:VCARD\r\nVERSION:2.1\r\nN:%s\r\nEMAIL:%s\r\nEND:VCARD\r\n" +#define BEGIN_BENV "BEGIN:BENV\r\n" +#define END_BENV "END:BENV\r\n" +#define BEGIN_BBODY "BEGIN:BBODY\r\n" +#define END_BBODY "END:BBODY\r\n" +#define ENCODING "ENCODING:%s\r\n" +#define CHARSET "CHARSET:%s\r\n" +#define LANGUAGE "LANGUAGE:%s\r\n" +#define LENGTH "LENGTH:%d\r\n" +#define MSG_BODY "BEGIN:MSG\r\n%s\r\nEND:MSG\r\n" +#define MSG_BODY_BEGIN "BEGIN:MSG\r\n" +#define MSG_BODY_END "\r\nEND:MSG\r\n" + +extern guint64 current_push_map_id; + +static void __bt_map_parse_moved_mails(char *inbuf, int *from_box_id, + int *to_box_id, GList **mail_list) +{ + if (!inbuf) + return; + + DBG("inbuf = %s", inbuf); + + /* notification format: <0x01><0x01><<,>>*/ + gchar **outer_tok; + char delimiter[2] = { 0x01, 0x00 }; + outer_tok = g_strsplit_set(inbuf, delimiter, -1); + if (outer_tok == NULL ) { + ERR("outer_tok == NULL"); + return; + } + if (outer_tok[0] && strlen(outer_tok[0]) > 0) + *from_box_id = atoi(outer_tok[0]); + if (outer_tok[1] && strlen(outer_tok[1]) > 0) + *to_box_id = atoi(outer_tok[1]); + if (outer_tok[2] && strlen(outer_tok[2]) > 0) { + gchar **inner_tok; + inner_tok = g_strsplit_set(outer_tok[2], ",", -1); + if (g_strv_length(inner_tok) == 1) { // only one mail_id exists without "," + int mail_id = atoi(outer_tok[2]); + *mail_list = g_list_append(*mail_list, (void *) mail_id); + } else { + int i; + for (i = 0; i < g_strv_length(inner_tok); ++i) { + if (!strcmp(inner_tok[i], "\"")) /* skip the empty token */ + continue; + else { + int mail_id = atoi(inner_tok[i]); + *mail_list = g_list_prepend(*mail_list, (void *) mail_id); + } + } + } + g_strfreev(inner_tok); + } + g_strfreev(outer_tok); + + *mail_list = g_list_reverse(*mail_list); +} + +char *__bt_email_get_path(int mailboxtype) +{ + switch (mailboxtype) { + case EMAIL_MAILBOX_TYPE_INBOX: + return g_strdup("TELECOM/MSG/INBOX"); + case EMAIL_MAILBOX_TYPE_SENTBOX: + return g_strdup("TELECOM/MSG/SENT"); + case EMAIL_MAILBOX_TYPE_TRASH: + return g_strdup("TELECOM/MSG/DELETED"); + case EMAIL_MAILBOX_TYPE_DRAFT: + return g_strdup("TELECOM/MSG/DRAFT"); + case EMAIL_MAILBOX_TYPE_OUTBOX: + return g_strdup("TELECOM/MSG/OUTBOX"); + } + return g_strdup(""); +} + +static void __bt_email_subscription_callback(GDBusConnection *connection, + const gchar *sender_name, const gchar *object_path, + const gchar *interface_name, const gchar *signal_name, + GVariant *parameters, gpointer data) +{ + int subtype = 0; + int data1 = 0; + int data2 = 0; + char *data3 = NULL; + int data4 = 0; + + g_variant_get(parameters, "(iii&si)", &subtype, &data1, + &data2, &data3, &data4); + + if ((g_strcmp0(object_path, BT_EMAIL_STORAGE_PATH)) || + (g_strcmp0(signal_name, BT_EMAIL_STORAGE_SIGNAL))) + return; + + if (subtype == NOTI_MAIL_ADD) { + /* Received values from Signal*/ + int account_id = data1; + int mailid = data2; + int mailbox_id = atoi(data3); + /* Fetch Values */ + int default_account_id = -1; + email_mailbox_t *mailbox = NULL; + guint64 handle; + + DBG("Mail Added[AccountID: %d, MailID:%d, MailBoxID:%d]", + account_id, mailid, mailbox_id); + + if (email_load_default_account_id(&default_account_id) + != EMAIL_ERROR_NONE) { + ERR("Could not load default account"); + return; + } + DBG("Default account_id: %d", default_account_id); + if (default_account_id != account_id) { + ERR("Event not meant for default email account"); + return; + } + + if (email_get_mailbox_by_mailbox_id(mailbox_id, + &mailbox) != EMAIL_ERROR_NONE) { + ERR("Could not get mailbox info"); + return; + } + + handle = _bt_add_id(mailid, BT_MAP_ID_EMAIL); + if (mailbox->mailbox_type == EMAIL_MAILBOX_TYPE_INBOX) { + _bt_mns_client_event_notify("NewMessage", handle, + "TELECOM/MSG/INBOX", "", + "EMAIL"); + } + if (mailbox) + email_free_mailbox(&mailbox, 1); + + } else if (subtype == NOTI_MAIL_MOVE_FINISH) { + /* Received values from Signal*/ + /* DATA1[account_id] DATA2[move_type] DATA4[??] + * DATA3[mailbox_id0x01updated_value0x01mail_id] */ + int account_id = data1; + int from_mailbox_id = -1; + int to_mailbox_id = -1; + GList *mail_ids = NULL; + + /* Fetch Values */ + int default_account_id = -1; + email_mailbox_t *mailbox_from = NULL; + email_mailbox_t *mailbox_to = NULL; + guint64 handle; + + __bt_map_parse_moved_mails(data3, &from_mailbox_id, + &to_mailbox_id, &mail_ids); + + DBG("Mail Moved[AccountID:%d From:%d, To:%d]", account_id, + from_mailbox_id, to_mailbox_id); + + if (email_load_default_account_id(&default_account_id) + != EMAIL_ERROR_NONE) { + ERR("Could not load default account"); + return; + } + DBG("Default account_id: %d", default_account_id); + if (default_account_id != account_id) { + ERR("Event not meant for default email account"); + return; + } + if (email_get_mailbox_by_mailbox_id(from_mailbox_id, &mailbox_from) + != EMAIL_ERROR_NONE) { + ERR("Could not get mailbox info"); + return; + } + if (email_get_mailbox_by_mailbox_id(to_mailbox_id, &mailbox_to) + != EMAIL_ERROR_NONE) { + ERR("Could not get mailbox info"); + if (from_mailbox_id) + email_free_mailbox(&mailbox_from, 1); + return; + } + + if (mailbox_to->mailbox_type == EMAIL_MAILBOX_TYPE_TRASH) { + while (mail_ids) { + int mailid = (int) mail_ids->data; + char *old_folder; + DBG("Mail ID[%d]", mailid); + if (mailid == 0) + break; + + old_folder = __bt_email_get_path(mailbox_from->mailbox_type); + handle = _bt_add_id(mailid, BT_MAP_ID_EMAIL); + DBG("[MessageDeleted] Handle:%d", handle); + _bt_mns_client_event_notify("MessageShift", handle, + "TELECOM/MSG/DELETED", old_folder, "EMAIL"); + g_free(old_folder); + mail_ids = g_list_next(mail_ids); + } + } else if (mailbox_to->mailbox_type == EMAIL_MAILBOX_TYPE_SENTBOX + && mailbox_from->mailbox_type == EMAIL_MAILBOX_TYPE_OUTBOX) { + while (mail_ids) { + int mailid = (int) mail_ids->data; + DBG("Mail ID[%d]", mailid); + if (mailid == 0) + break; + + handle = _bt_add_id(mailid, BT_MAP_ID_EMAIL); + DBG("[SendingSuccess] Handle:%d", handle); + + _bt_mns_client_event_notify("MessageShift", handle, + "TELECOM/MSG/SENT", "TELECOM/MSG/OUTBOX", "EMAIL"); + + _bt_mns_client_event_notify("SendingSuccess", handle, + "TELECOM/MSG/SENT", "", "EMAIL"); + mail_ids = g_list_next(mail_ids); + } + } + if (mailbox_to) + email_free_mailbox(&mailbox_to, 1); + if (mailbox_from) + email_free_mailbox(&mailbox_from, 1); + } +} + +gboolean _bt_map_start_email_service(void) +{ + int err; + GDBusConnection *dbus_conn = NULL; + GError *error = NULL; + int signal_handler_storage = -1; + err = email_service_begin(); + if (err != EMAIL_ERROR_NONE) { + ERR("email_service_begin fail error = %d\n", err); + return FALSE; + } + + dbus_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error); + if (error) { + ERR("g_bus_get_sync() failed (%s)", error->message); + g_error_free(error); + email_service_end(); + return FALSE; + } + + signal_handler_storage = g_dbus_connection_signal_subscribe(dbus_conn, + NULL, BT_EMAIL_STORAGE_INTERFACE, BT_EMAIL_STORAGE_SIGNAL, + BT_EMAIL_STORAGE_PATH, NULL, G_DBUS_SIGNAL_FLAGS_NONE, + __bt_email_subscription_callback, NULL, NULL); + + if (signal_handler_storage == -1) { + ERR("Failed to g_dbus_connection_signal_subscribe()"); + g_object_unref(dbus_conn); + email_service_end(); + return FALSE; + } + + return TRUE; +} + +gboolean _bt_map_stop_email_service(void) +{ + int err; + + err = email_service_end(); + if (err != EMAIL_ERROR_NONE) { + ERR("email_service_end fail error = %d\n", err); + return FALSE; + } + + return TRUE; +} + +gboolean _bt_map_email_get_supported_folders(gboolean folders[FOLDER_COUNT][MSG_TYPES]) +{ + DBG(""); + int account_id = 0; + int mailbox_count = 0; + int err; + int i; + email_mailbox_t *mailbox_list = NULL; + email_mailbox_t *temp = NULL; + + err = email_load_default_account_id(&account_id); + if (err != EMAIL_ERROR_NONE) + return FALSE; + + err = email_get_mailbox_list(account_id, EMAIL_MAILBOX_ALL, + &mailbox_list, &mailbox_count); + if (err != EMAIL_ERROR_NONE) + return FALSE; + + DBG("Count: %d", mailbox_count); + for (i = 0, temp = mailbox_list; i < mailbox_count; i++, temp++) { + DBG("Folder:%s", temp->mailbox_name); + if (!g_ascii_strncasecmp(temp->mailbox_name, "SENT", strlen("SENT"))) { + folders[BT_MSG_SENT][BT_MSG_SOURCE_EMAIL] = TRUE; + DBG("SENT"); + } else if (!g_ascii_strncasecmp(temp->mailbox_name, "DRAFT", strlen("DRAFT"))) { + folders[BT_MSG_DRAFT][BT_MSG_SOURCE_EMAIL] = TRUE; + DBG("DRAFT"); + } else if (!g_ascii_strncasecmp(temp->mailbox_name, "DELETED", strlen("DELETED")) || + !g_ascii_strncasecmp(temp->mailbox_name, "TRASH", strlen("TRASH"))) { + folders[BT_MSG_DELETED][BT_MSG_SOURCE_EMAIL] = TRUE; + DBG("DELETED"); + } else if (!g_ascii_strncasecmp(temp->mailbox_name, "INBOX", strlen("INBOX"))) { + folders[BT_MSG_INBOX][BT_MSG_SOURCE_EMAIL] = TRUE; + DBG("INBOX"); + } else if (!g_ascii_strncasecmp(temp->mailbox_name, "OUTBOX", strlen("OUTBOX"))) { + folders[BT_MSG_OUTBOX][BT_MSG_SOURCE_EMAIL] = TRUE; + DBG("OUTBOX"); + } else if (!g_ascii_strncasecmp(temp->mailbox_name, "[gmail]", strlen("[gmail]"))) { + DBG("GMAIL Folder"); + if (!g_ascii_strncasecmp(temp->mailbox_name, "[Gmail]/Drafts", strlen("[Gmail]/Drafts"))) { + folders[BT_MSG_DRAFT][BT_MSG_SOURCE_EMAIL] = TRUE; + DBG("[Gmail]/DRAFT"); + } else if (!g_ascii_strncasecmp(temp->mailbox_name, "[Gmail]/Sent", strlen("[Gmail]/Sent"))) { + folders[BT_MSG_SENT][BT_MSG_SOURCE_EMAIL] = TRUE; + DBG("[Gmail]/SENT"); + } else if (!g_ascii_strncasecmp(temp->mailbox_name, "[Gmail]/Trash", strlen("[Gmail]/Trash"))) { + folders[BT_MSG_DELETED][BT_MSG_SOURCE_EMAIL] = TRUE; + DBG("[Gmail]/Trash"); + } + } + } + + if (mailbox_list != NULL) + email_free_mailbox(&mailbox_list, mailbox_count); + + return TRUE; +} + +static message_info_t *__bt_email_info_get(email_mail_list_item_t *email_struct, + guint8 subject_len) +{ + message_info_t *email_info = NULL; + email_mail_data_t *mail_data; + guint64 uid = 0; + time_t dptime; + char email_handle[BT_MAP_MSG_HANDLE_MAX] = {0,}; + char msg_datetime[BT_MAP_TIMESTAMP_MAX_LEN] = {0,}; + email_info = g_new0(message_info_t, 1); + + uid = _bt_add_id(email_struct->mail_id, BT_MAP_ID_EMAIL); + snprintf(email_handle, sizeof(email_handle), "%llx", uid); + DBG("******* MAP ID:%d, MailID:%d **********", uid, email_struct->mail_id); + email_info->handle = g_strdup(email_handle); + + dptime = email_struct->date_time; + _get_msg_timestamp(&dptime, msg_datetime); + + email_info->sender_name = g_strdup(email_struct->email_address_sender); + email_info->sender_addressing = g_strdup(email_struct->email_address_sender); + email_info->recipient_name = g_strdup(email_struct->email_address_recipient); + email_info->recipient_addressing = g_strdup(email_struct->email_address_recipient); + + email_info->subject = g_strndup(email_struct->subject, subject_len); + email_info->datetime = g_strdup(msg_datetime); + email_info->time = dptime; // for sorting + email_info->type = g_strdup("EMAIL"); + email_info->size = g_strdup_printf("%d", email_struct->mail_size); + email_info->reception_status = g_strdup("complete"); + email_info->attachment_size = g_strdup("0"); + email_info->replyto_addressing = g_strdup( + email_struct->email_address_sender); + + DBG("Seen Status: %d", email_struct->flags_seen_field); + if (email_struct->flags_seen_field) + email_info->read = TRUE; + else + email_info->read = FALSE; + + DBG("Priority: %d", email_struct->priority); + if (email_struct->priority == EMAIL_MAIL_PRIORITY_HIGH) + email_info->priority = TRUE; + else + email_info->priority = FALSE; + + email_info->text = FALSE; + email_info->protect = FALSE; + + if (email_get_mail_data(email_struct->mail_id, &mail_data) != EMAIL_ERROR_NONE) { + ERR("email_get_mail_data failed\n"); + return email_info; + } + + if (mail_data->alias_sender) { + g_free(email_info->sender_name); + email_info->sender_name = g_strdup(mail_data->alias_sender); + } + + if (mail_data->alias_recipient) { + g_free(email_info->recipient_name); + email_info->recipient_name = g_strdup(mail_data->alias_recipient); + } + + email_info->recipient_addressing = g_strdup(mail_data->email_address_recipient); + + return email_info; +} + +static gboolean __bt_map_email_compare_folders(char *alias, char *folder) +{ + DBG("Folder:%s, Alias:%s", folder, alias); + + char *map_folder = NULL; + + if (!g_ascii_strncasecmp(alias, "SENT", strlen("SENT"))) { + map_folder = "SENT"; + } else if (!g_ascii_strncasecmp(alias, "DRAFT", strlen("DRAFT"))) { + map_folder = "DRAFT"; + } else if (!g_ascii_strncasecmp(alias, "DELETED", strlen("DELETED")) || + !g_ascii_strncasecmp(alias, "TRASH", strlen("TRASH"))) { + map_folder = "DELETED"; + } else if (!g_ascii_strncasecmp(alias, "INBOX", strlen("INBOX"))) { + map_folder = "INBOX"; + } else if (!g_ascii_strncasecmp(alias, "OUTBOX", strlen("OUTBOX"))) { + map_folder = "OUTBOX"; + } else if (!g_ascii_strncasecmp(alias, "[gmail]", strlen("[gmail]"))) { + DBG("GMAIL Folders"); + if (!g_ascii_strncasecmp(alias, "[Gmail]/Drafts", strlen("[Gmail]/Drafts"))) { + map_folder = "DRAFT"; + } else if (!g_ascii_strncasecmp(alias, "[Gmail]/Sent", strlen("[Gmail]/Sent"))) { + map_folder = "SENT"; + } else if (!g_ascii_strncasecmp(alias, "[Gmail]/Trash", strlen("[Gmail]/Trash"))) { + map_folder = "DELETED"; + } + } + + DBG("Equivalent MAP Folder for Alias: %s", map_folder); + if (map_folder && g_ascii_strcasecmp(map_folder, folder) == 0) + return TRUE; + + return FALSE; +} + +gboolean _bt_map_get_email_list(char *folder, int max, + guint8 subject_len, map_msg_filter_t *filter, + GSList **email_list, guint64 *count, gboolean *newmsg) +{ + DBG(""); + int i; + int ret; + int total = 0; + int account_id = 0; + int mailbox_count = 0; + int mail_count = 0; + int msg_count = 0; + char *type = NULL; + + email_mailbox_t *mailbox_list = NULL; + email_mail_list_item_t *mail_list = NULL; + email_mail_list_item_t *temp = NULL; + email_list_filter_t *filter_list = NULL; + email_list_sorting_rule_t *sorting_rule_list = NULL; + GSList *list = NULL; + + if (max == 0) + max = 1024; + + ret = email_load_default_account_id(&account_id); + if (ret != EMAIL_ERROR_NONE) + return FALSE; + DBG("Account ID:%d", account_id); + + ret = email_get_mailbox_list(account_id, EMAIL_MAILBOX_ALL, + &mailbox_list, &mailbox_count); + if (ret != EMAIL_ERROR_NONE || mailbox_list == NULL) + return FALSE; + + for (i = 0; i < mailbox_count; i++) { + DBG("mailbox alias = %s \n", mailbox_list[i].alias); + /* Optimize using mailbox_type */ + if (__bt_map_email_compare_folders(mailbox_list[i].mailbox_name, folder)) { + total = mailbox_list[i].total_mail_count_on_server; + DBG("Total mail on sever:%d\n", total); + DBG("mailbox name:%s\n", mailbox_list[i].mailbox_name); + DBG("mailbox ID:%d\n", mailbox_list[i].mailbox_id); + break; + } + } + DBG(""); + if (total == 0) { + email_free_mailbox(&mailbox_list, mailbox_count); + return FALSE; + } + DBG(""); + filter_list = g_new0(email_list_filter_t, 3); + filter_list[0].list_filter_item_type = EMAIL_LIST_FILTER_ITEM_RULE; + filter_list[0].list_filter_item.rule.target_attribute = EMAIL_MAIL_ATTRIBUTE_ACCOUNT_ID; + filter_list[0].list_filter_item.rule.rule_type = EMAIL_LIST_FILTER_RULE_EQUAL; + filter_list[0].list_filter_item.rule.key_value.integer_type_value = account_id; + + filter_list[1].list_filter_item_type = EMAIL_LIST_FILTER_ITEM_OPERATOR; + filter_list[1].list_filter_item.operator_type = EMAIL_LIST_FILTER_OPERATOR_AND; + + filter_list[2].list_filter_item_type = EMAIL_LIST_FILTER_ITEM_RULE; + filter_list[2].list_filter_item.rule.target_attribute = EMAIL_MAIL_ATTRIBUTE_MAILBOX_ID; + filter_list[2].list_filter_item.rule.rule_type = EMAIL_LIST_FILTER_RULE_EQUAL; + filter_list[2].list_filter_item.rule.key_value.integer_type_value = mailbox_list[i].mailbox_id; + DBG("mailbox ID:%d\n", mailbox_list[i].mailbox_id); + + sorting_rule_list = g_new0(email_list_sorting_rule_t, 1); + sorting_rule_list[0].target_attribute = EMAIL_MAIL_ATTRIBUTE_DATE_TIME; + sorting_rule_list[0].sort_order = EMAIL_SORT_ORDER_DESCEND; + sorting_rule_list[0].force_boolean_check = false; + + ret = email_get_mail_list_ex(filter_list, 3, sorting_rule_list, 1, -1, + -1, &mail_list, &mail_count); + if (ret != EMAIL_ERROR_NONE) { + DBG("Error Code:%d", ret); + g_free(type); + g_free(filter_list); + g_free(sorting_rule_list); + return FALSE; + } + + DBG("Mail Count: %d", mail_count); + max = (max > mail_count) ? (mail_count) : max; + DBG("Max:%d", max); + for (i = 0, temp = mail_list; i < mail_count && msg_count < max; ++i, temp++) { + message_info_t *email_info; + + email_info = __bt_email_info_get(temp, subject_len); + + if (!_bt_verify_read_status(email_info, filter->read_status) || + !_bt_verify_receiver(email_info, filter->recipient) || + !_bt_verify_sender(email_info, filter->originator) || + !_bt_verify_time(email_info, filter) || + !_bt_filter_priority(email_info, filter->priority) || + !_bt_validate_msg_data(email_info)) { + _bt_message_info_free((gpointer)email_info); + continue; + } + + list = g_slist_append(list, email_info); + msg_count++; + } + + *count = (guint64)mail_count; + *email_list = list; + + email_free_mailbox(&mailbox_list, mailbox_count); + + if (mail_list) + free(mail_list); + + g_free(filter_list); + g_free(sorting_rule_list); + g_free(type); + DBG("EXIT"); + return TRUE; +} + +gboolean _bt_map_update_mailbox(char *folder) +{ + int handle; + int ret; + + ret = email_sync_header_for_all_account(&handle); + if (ret == EMAIL_ERROR_NONE) { + DBG("Handle to stop download = %d \n", handle); + } else { + ERR("Message Update failed \n"); + return FALSE; + } + + return TRUE; +} + +gboolean _bt_map_set_email_read_status(int mail_id, int read_status) +{ + int ret; + email_mail_data_t *mail_data = NULL; + + ret = email_get_mail_data(mail_id, &mail_data); + if (ret != EMAIL_ERROR_NONE) { + ERR("email_get_mail_data failed\n"); + return FALSE; + } + + ret = email_set_flags_field(mail_data->account_id, &mail_id, 1, + EMAIL_FLAGS_SEEN_FIELD, read_status, 0); + if (ret != EMAIL_ERROR_NONE) { + email_free_mail_data(&mail_data, 1); + return FALSE; + } + + email_free_mail_data(&mail_data, 1); + return TRUE; +} + +gboolean _bt_map_set_email_delete_status(int mail_id, int read_status) +{ + int ret; + email_mail_data_t *mail_data = NULL; + + ret = email_get_mail_data(mail_id, &mail_data); + if (ret != EMAIL_ERROR_NONE) + return FALSE; + + ret = email_delete_mail(mail_data->mailbox_id, &mail_id, 1, 1); + if (ret != EMAIL_ERROR_NONE) { + email_free_mail_data(&mail_data, 1); + return FALSE; + } + + email_free_mail_data(&mail_data, 1); + return TRUE; +} + +static gchar *__bt_get_email_folder_name(int mailboxtype) +{ + switch (mailboxtype) { + case EMAIL_MAILBOX_TYPE_SENTBOX: + return g_strdup("TELECOM/MSG/SENT"); + case EMAIL_MAILBOX_TYPE_TRASH: + return g_strdup("TELECOM/MSG/DELETED"); + case EMAIL_MAILBOX_TYPE_OUTBOX: + return g_strdup("TELECOM/MSG/OUTBOX"); + case EMAIL_MAILBOX_TYPE_DRAFT: + return g_strdup("TELECOM/MSG/DRAFT"); + default: + return g_strdup("TELECOM/MSG/INBOX"); + } +} + +static char *__bt_prepare_email_bmseg(email_mail_data_t *mail_data) +{ + FN_START; + char *folder = NULL; + FILE *body_file; + long read_size; + long email_size; + GString *msg; + char *buf = NULL; + + msg = g_string_new(BEGIN_BMSEG); + g_string_append(msg, BMSEG_VERSION); + + DBG("Seen Flag: %d", mail_data->flags_seen_field); + if (mail_data->flags_seen_field) + g_string_append_printf(msg, MSEG_STATUS, "READ"); + else + g_string_append_printf(msg, MSEG_STATUS, "UNREAD"); + + g_string_append_printf(msg, MSEG_TYPE, "EMAIL"); + + folder = __bt_get_email_folder_name(mail_data->mailbox_type); + g_string_append_printf(msg, FOLDER_PATH, folder); + g_free(folder); + + /* List of recepient & sender */ + DBG("Sender: %d", mail_data->email_address_sender); + DBG("Sender Alias: %d", mail_data->alias_sender); + g_string_append_printf(msg, EMAIL_VCARD, mail_data->email_address_sender, + mail_data->email_address_sender); + + g_string_append(msg, BEGIN_BENV); + g_string_append(msg, BEGIN_BBODY); + + + g_string_append_printf(msg, CHARSET, "UTF-8"); + g_string_append_printf(msg, ENCODING, "8BIT"); + DBG("Plain Message file: %s", mail_data->file_path_plain); + DBG("HTML Message file: %s", mail_data->file_path_html); + body_file = fopen(mail_data->file_path_plain, "r"); + if (body_file == NULL) { + DBG("NOT PLAIN TEXT MESSAGE"); + body_file = fopen(mail_data->file_path_html, "rb"); + } + + if (body_file != NULL) { + fseek(body_file, 0, SEEK_END); + email_size = ftell(body_file); + rewind(body_file); + + buf = (char *)g_malloc0(sizeof(char) * email_size); + read_size = fread(buf, 1, email_size, body_file); + fclose(body_file); + DBG("MESSAGE: [%s]", buf); + if (read_size != email_size) { + ERR("Unequal Read size"); + email_free_mail_data(&mail_data, 1); + g_string_free(msg, TRUE); + g_free(buf); + return NULL; + } + } else { + DBG("BODY of the MESSAGE NOT FOUND"); + buf = (char *)g_strdup(""); + } + + g_string_append_printf(msg, LENGTH, strlen(buf)); + + g_string_append_printf(msg, MSG_BODY, buf); + + + g_string_append(msg, END_BBODY); + g_string_append(msg, END_BENV); + g_string_append(msg, END_BMSEG); + g_free(buf); + + FN_END; + return g_string_free(msg, FALSE); +} + +gboolean _bt_map_get_email_message(int mail_id, gboolean attach, + gboolean transcode, gboolean first_request, gchar **bmseg) +{ + DBG("ENTER==>"); + int account_id; + int ret; + email_mail_data_t *mail_data = NULL; + + ret = email_load_default_account_id(&account_id); + if (ret != EMAIL_ERROR_NONE) + return FALSE; + + ret = email_get_mail_data(mail_id, &mail_data); + if (ret != EMAIL_ERROR_NONE) + return FALSE; + + *bmseg = __bt_prepare_email_bmseg(mail_data); + + email_free_mail_data(&mail_data, 1); + DBG("EXIT==>"); + return TRUE; +} + +static int __bt_map_save_email_to_outbox(char *subject, char *body, + char *recepients) +{ + int type = EMAIL_MAILBOX_TYPE_OUTBOX; + int account_id; + int mail_id = -1; + int ret; + struct stat st_buf; + FILE *body_file; + + email_account_t *account_data = NULL; + email_mailbox_t *mailbox_data = NULL; + email_mail_data_t *mail_data = NULL; + + DBG("email_mailbox_type_e :%d", type); + DBG("Subject: %s", subject); + DBG("Body: %s", body); + DBG("Recepients: %s", recepients); + + ret = email_load_default_account_id(&account_id); + if (ret != EMAIL_ERROR_NONE) + goto fail; + + DBG("account_id %d", account_id); + ret = email_get_mailbox_by_mailbox_type(account_id, type, + &mailbox_data); + if (ret != EMAIL_ERROR_NONE) + goto fail; + + ret = email_get_account(account_id, EMAIL_ACC_GET_OPT_FULL_DATA, + &account_data); + if (ret != EMAIL_ERROR_NONE) + goto fail; + + mail_data = calloc(1, sizeof(email_mail_data_t)); + if (mail_data == NULL) { + ERR("Allocation Failed"); + goto fail; + } + + mail_data->account_id = account_id; + mail_data->save_status = EMAIL_MAIL_STATUS_SEND_DELAYED; + mail_data->body_download_status = 1; + mail_data->flags_seen_field = 1; + mail_data->report_status = EMAIL_MAIL_REQUEST_DSN | + EMAIL_MAIL_REQUEST_MDN; + mail_data->remaining_resend_times = 3; + mail_data->file_path_plain = g_strdup(BT_MAIL_TEMP_BODY); + mail_data->subject = g_strdup(subject); + mail_data->full_address_to = g_strdup(recepients); + + /* Get Sender Address from Account data*/ + mail_data->full_address_from = g_strdup(account_data->user_email_address); + + /* Get MailboxID and Type from mailbox data */ + mail_data->mailbox_id = mailbox_data->mailbox_id; + mail_data->mailbox_type = mailbox_data->mailbox_type; + + /* Save Body to a File */ + body_file = fopen(BT_MAIL_TEMP_BODY, "w"); + if (body_file == NULL) { + ERR("fopen [%s]failed", BT_MAIL_TEMP_BODY); + goto fail; + } + + ret = fprintf(body_file, "%s", body); + fflush(body_file); + fclose(body_file); + + /* Save Email */ + ret = email_add_mail(mail_data, NULL, 0, NULL, 0); + if (ret != EMAIL_ERROR_NONE) { + DBG("email_add_mail failed. [%d]\n", ret); + if (!stat(mail_data->file_path_plain, &st_buf)) + remove(mail_data->file_path_plain); + + goto fail; + } + + DBG("saved mail id = [%d]\n", mail_data->mail_id); + mail_id = mail_data->mail_id; + +fail: + if (mailbox_data) + email_free_mailbox(&mailbox_data, 1); + if (account_data) + email_free_account(&account_data, 1); + if (mail_data) + email_free_mail_data(&mail_data, 1); + + return mail_id; +} + +static int __bt_map_save_email_to_draft(char *subject, + char *body, char *recepients) +{ + int type = EMAIL_MAILBOX_TYPE_DRAFT; + int account_id; + int mail_id = -1; + int ret; + struct stat st_buf; + FILE *body_file; + + email_account_t *account_data = NULL; + email_mailbox_t *mailbox_data = NULL; + email_mail_data_t *mail_data = NULL; + + DBG("email_mailbox_type_e :%d", type); + DBG("Subject: %s", subject); + DBG("Body: %s", body); + DBG("Recepients: %s", recepients); + + ret = email_load_default_account_id(&account_id); + if (ret != EMAIL_ERROR_NONE) + goto fail; + + DBG("account_id %d", account_id); + ret = email_get_mailbox_by_mailbox_type(account_id, type, + &mailbox_data); + if (ret != EMAIL_ERROR_NONE) + goto fail; + + ret = email_get_account(account_id, EMAIL_ACC_GET_OPT_FULL_DATA, + &account_data); + if (ret != EMAIL_ERROR_NONE) + goto fail; + + mail_data = calloc(1, sizeof(email_mail_data_t)); + if (mail_data == NULL) { + ERR("Allocation Failed"); + goto fail; + } + + mail_data->account_id = account_id; + mail_data->body_download_status = 1; + mail_data->flags_seen_field = 1; + mail_data->flags_draft_field = 1; + mail_data->report_status = EMAIL_MAIL_REPORT_NONE; + mail_data->remaining_resend_times = -1; + mail_data->subject = g_strdup(subject); + mail_data->full_address_to = g_strdup(recepients); + + /* Get Sender Address from Account data*/ + mail_data->full_address_from = g_strdup(account_data->user_email_address); + email_free_account(&account_data, 1); + + /* Get MailboxID and Type from mailbox data */ + mail_data->mailbox_id = mailbox_data->mailbox_id; + mail_data->mailbox_type = mailbox_data->mailbox_type; + email_free_mailbox(&mailbox_data, 1); + + /* Save Body to a File */ + mail_data->file_path_plain = g_strdup(BT_MAIL_TEMP_BODY); + + body_file = fopen(BT_MAIL_TEMP_BODY, "w"); + if (body_file == NULL) { + ERR("fopen [%s]failed", BT_MAIL_TEMP_BODY); + goto fail; + } + + ret = fprintf(body_file, "%s", body); + fflush(body_file); + fclose(body_file); + + /* Save Email */ + ret = email_add_mail(mail_data, NULL, 0, NULL, 0); + if (ret != EMAIL_ERROR_NONE) { + DBG("email_add_mail failed. [%d]\n", ret); + if (!stat(mail_data->file_path_plain, &st_buf)) + remove(mail_data->file_path_plain); + + goto fail; + } + + DBG("saved mail id = [%d]\n", mail_data->mail_id); + mail_id = mail_data->mail_id; + +fail: + if (mailbox_data) + email_free_mailbox(&mailbox_data, 1); + if (account_data) + email_free_account(&account_data, 1); + if (mail_data) + email_free_mail_data(&mail_data, 1); + + return mail_id; +} + +static int __bt_map_send_email(char *subject, char *body, + char *recepients, gboolean send) +{ + int ret; + int mail_id = -1; + int handle; + + if (send) { + DBG("Send Mail"); + mail_id = __bt_map_save_email_to_outbox(subject, + body, recepients); + if (mail_id) { + DBG("mail_id = %d\n", mail_id); + ret = email_send_mail(mail_id, &handle); + if (ret != EMAIL_ERROR_NONE) + DBG("Sending failed[%d]\n", ret); + } + + } else { + DBG("Save to Draft"); + mail_id = __bt_map_save_email_to_draft(subject, + body, recepients); + } + + return mail_id; +} + +static char *__bt_map_get_email_address(GSList *recepients) +{ + GString *mailto = NULL; + + while (recepients) { + char *address = recepients->data; + DBG("Email: %s", address); + if (email_verify_email_address(address) == EMAIL_ERROR_NONE) { + if (mailto == NULL) { + mailto = g_string_new(address); + } else { + g_string_append(mailto, "; "); + g_string_append(mailto, address); + } + } + recepients = g_slist_next(recepients); + } + + return g_string_free(mailto, FALSE); +} + +gboolean _bt_map_push_email_data(struct bmsg_data *bmsg_info, + msg_send_option_t *option, char *folder) +{ + FN_START; + int id = -1; + char *message = NULL; + char *body = NULL; + char *subject = NULL; + GSList *recepients = NULL; + gboolean send = FALSE; + char *mailto = NULL; + + DBG("Length of Folder String: %d", strlen(bmsg_info->folder)); + if (strlen(bmsg_info->folder) == 0) { + DBG("No Folder Info. Default to OUTBOX"); + bmsg_info->folder = g_strdup(folder); + } + + DBG("FOLDER: %s", bmsg_info->folder); + if (!g_ascii_strcasecmp(bmsg_info->folder, "OUTBOX") || + !g_ascii_strcasecmp(bmsg_info->folder, "TELECOM/MSG/OUTBOX")) + send = TRUE; + + message = bmsg_get_msg_body(bmsg_info, option->native); + if (message == NULL) + goto done; + DBG_SECURE("Message: %s", message); + + if (!bmsg_parse_msg_body(message, &body, &subject)) + goto done; + DBG_SECURE("SUBJECT: %s", subject); + DBG_SECURE("BODY: %s", body); + + recepients = bmsg_get_msg_recepients(bmsg_info, BT_MAP_ID_EMAIL); + + mailto = __bt_map_get_email_address(recepients); + DBG("Email IDs: %s", mailto); + + /* TODO : Write logic to Get Subject from bmessage + */ + + id = __bt_map_send_email(subject, body, mailto, send); + if (id == -1) + goto done; + + _bt_update_id(current_push_map_id, id, BT_MAP_ID_EMAIL); + +done: + g_free(body); + g_free(subject); + g_free(message); + g_slist_free(recepients); + + if (id == -1) { + FN_END; + return FALSE; + } + + return TRUE; +} diff --git a/map-agent/bluetooth_map_email.h b/map-agent/bluetooth_map_email.h new file mode 100644 index 0000000..538781e --- /dev/null +++ b/map-agent/bluetooth_map_email.h @@ -0,0 +1,53 @@ +/* + * Bluetooth-agent + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Hocheol Seo + * Girishashok Joshi + * Chanyeol Park + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef __DEF_MAP_EMAIL_H_ +#define __DEF_MAP_EMAIL_H_ + +#include +#include "bluetooth_map_types.h" +#include "map_bmessage.h" + +gboolean _bt_map_start_email_service(void); + +gboolean _bt_map_stop_email_service(void); + +gboolean _bt_map_email_get_supported_folders(gboolean folders[FOLDER_COUNT][MSG_TYPES]); + +gboolean _bt_map_get_email_list(char *folder, int max, + guint8 subject_len, map_msg_filter_t *filter, + GSList **email_list, guint64 *count, gboolean *newmsg); + +gboolean _bt_map_update_mailbox(char *folder); + +gboolean _bt_map_set_email_read_status(int mail_id, int read_status); + +gboolean _bt_map_set_email_delete_status(int mail_id, int read_status); + +gboolean _bt_map_get_email_message(int mail_id, gboolean attach, + gboolean transcode, gboolean first_request, gchar **bmseg); + +gboolean _bt_map_push_email_data(struct bmsg_data *bmsg_info, + msg_send_option_t *option, char *folder); + +#endif /* __DEF_MAP_EMAIL_H_ */ diff --git a/map-agent/bluetooth_map_sms.c b/map-agent/bluetooth_map_sms.c new file mode 100644 index 0000000..acc0bd3 --- /dev/null +++ b/map-agent/bluetooth_map_sms.c @@ -0,0 +1,1188 @@ +/* + * Bluetooth-agent + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Hocheol Seo + * Syam Sidhardhan + * Chanyeol Park + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include +#include + +/*Messaging Header Files*/ +#include "msg.h" +#include "msg_storage.h" +#include "msg_storage_types.h" +#include "msg_transport.h" +#include "msg_transport_types.h" +#include "msg_types.h" + +#include + +#define BT_MAP_STATUS_CB "sent status callback" +#define BT_MAP_MSG_CB "sms message callback" +#define BT_MAP_DELETED_FOLDER_NAME "DELETED" +#define BT_MAP_SENT_FOLDER_NAME "SENT" +#define BT_MAP_MSG_TEMPLATE "TEMPLATE" + +#define BT_MAP_MSG_INFO_MAX 256 +#define BT_MAP_MSG_HANDLE_MAX 21 +#define BT_MAP_TIMESTAMP_MAX_LEN 16 +#define BT_MAP_MSG_BODY_MAX 1024 + +#define BEGIN_BMSEG "BEGIN:BMSG\r\n" +#define END_BMSEG "END:BMSG\r\n" +#define BMSEG_VERSION "VERSION:1.0\r\n" +#define MSEG_STATUS "STATUS:%s\r\n" +#define MSEG_TYPE "TYPE:%s\r\n" +#define FOLDER_PATH "FOLDER:%s\r\n" +#define VCARD "BEGIN:VCARD\r\nVERSION:2.1\r\nN:%s\r\nTEL:%s\r\nEND:VCARD\r\n" +#define BEGIN_BENV "BEGIN:BENV\r\n" +#define END_BENV "END:BENV\r\n" +#define BEGIN_BBODY "BEGIN:BBODY\r\n" +#define END_BBODY "END:BBODY\r\n" +#define ENCODING "ENCODING:%s\r\n" +#define CHARSET "CHARSET:%s\r\n" +#define LANGUAGE "LANGUAGE:%s\r\n" +#define LENGTH "LENGTH:%d\r\n" +#define MSG_BODY "BEGIN:MSG\r\n%s\r\nEND:MSG\r\n" +#define MSG_BODY_BEGIN "BEGIN:MSG\r\n" +#define MSG_BODY_END "\r\nEND:MSG\r\n" + +static msg_handle_t g_msg_handle = NULL; +extern guint64 current_push_map_id; + +static int __bt_get_sms_folder_id(char *folder_path) +{ + FN_START; + int folder_id = -1; + int i; + char *folder; + msg_struct_list_s folder_list = {0,}; + msg_error_t err; + msg_struct_t p_folder; + DBG_SECURE("folder_path %s\n", folder_path); + + folder = strrchr(folder_path, '/'); + if (NULL == folder) + folder = folder_path; + else + folder++; + + err = msg_get_folder_list(g_msg_handle, &folder_list); + if (err != MSG_SUCCESS) + goto done; + + for (i = 0; i < folder_list.nCount; i++) { + char folder_name[BT_MAP_MSG_INFO_MAX] = {0, }; + + p_folder = folder_list.msg_struct_info[i]; + + err = msg_get_str_value(p_folder, MSG_FOLDER_INFO_NAME_STR, + folder_name, BT_MAP_MSG_INFO_MAX); + if (err != MSG_SUCCESS) + continue; + + DBG_SECURE("folder_name %s\n", folder_name); + if (!g_ascii_strncasecmp(folder_name, folder, strlen(folder))) { + err = msg_get_int_value(p_folder, + MSG_FOLDER_INFO_ID_INT, + &folder_id); + if (err != MSG_SUCCESS) + goto done; + + DBG("folder_id %d", folder_id); + break; + } + } + +done: + if (folder_list.msg_struct_info) + msg_release_list_struct(&folder_list); + + FN_END; + return folder_id; + +} + + +static void __bt_add_deleted_folder(void) +{ + FN_START; + msg_error_t err; + msg_struct_t folder_info = msg_create_struct(MSG_STRUCT_FOLDER_INFO); + + err = msg_set_int_value(folder_info, MSG_FOLDER_INFO_TYPE_INT, + MSG_FOLDER_TYPE_USER_DEF); + if (err != MSG_SUCCESS) { + ERR("Failed adding type %d", err); + msg_release_struct(&folder_info); + return; + } + + err = msg_set_str_value(folder_info, MSG_FOLDER_INFO_NAME_STR, + "DELETED", MAX_FOLDER_NAME_SIZE); + if (err != MSG_SUCCESS) { + ERR("Failed adding str %d", err); + msg_release_struct(&folder_info); + return; + } + + err = msg_add_folder(g_msg_handle, folder_info); + if (err != MSG_SUCCESS) { + ERR("Failed adding folder %d", err); + msg_release_struct(&folder_info); + return; + } + + msg_release_struct(&folder_info); + FN_END; +} + +static void __bluetooth_map_msg_incoming_status_cb(msg_handle_t handle, + msg_struct_t msg, + void *user_param) +{ + FN_START; + int msg_id = 0; + int msg_type = 0; + int ret; + + guint64 uid; + + if (is_mns_connected() == FALSE) { + INFO("MNS Client not connected"); + return; + } + + ret = msg_get_int_value(msg, MSG_MESSAGE_TYPE_INT, &msg_type); + if (ret != MSG_SUCCESS) + return; + + if (msg_type != MSG_TYPE_SMS) { + INFO("Not a SMS"); + return; + } + + ret = msg_get_int_value(msg, MSG_MESSAGE_ID_INT, &msg_id); + if (ret != MSG_SUCCESS) + return; + + uid = _bt_add_id(msg_id, BT_MAP_ID_SMS); + + _bt_mns_client_event_notify("NewMessage", uid, + "TELECOM/MSG/INBOX", "", + "SMS_GSM"); + + FN_END; +} + +static void __bluetooth_map_msg_sent_status_cb(msg_handle_t handle, + msg_struct_t msg, + void *user_param) +{ + FN_START; + int ret; + int status; + + if (is_mns_connected() == FALSE) { + INFO("MNS Client not connected"); + return; + } + + ret = msg_get_int_value(msg, MSG_SENT_STATUS_NETWORK_STATUS_INT, + &status); + if (ret != MSG_SUCCESS) + return; + + if (status == MSG_NETWORK_SEND_SUCCESS) { + INFO("MSG SENT SUCCESS !!! "); + _bt_mns_client_event_notify("MessageShift", + current_push_map_id, + "TELECOM/MSG/SENT", + "TELECOM/MSG/OUTBOX", + "SMS_GSM"); + + _bt_mns_client_event_notify("SendingSuccess", + current_push_map_id, + "TELECOM/MSG/SENT", "", + "SMS_GSM"); + } else { + ERR("MSG SENT FAIL !!! [%d]", status); + _bt_mns_client_event_notify("SendingFailure", + current_push_map_id, + "TELECOM/MSG/OUTBOX", "", + "SMS_GSM"); + } + + FN_END; +} + +gboolean _bt_map_sms_get_supported_folders(gboolean folders[FOLDER_COUNT][MSG_TYPES]) +{ + FN_START; + char folder_name[BT_MAP_MSG_INFO_MAX] = {0,}; + int i; + int ret; + gboolean msg_ret = TRUE; + + msg_struct_list_s folder_list = {0,}; + msg_struct_t p_folder; + + if (g_msg_handle == NULL) { + msg_ret = FALSE; + goto done; + } + + if (msg_get_folder_list(g_msg_handle, &folder_list) != MSG_SUCCESS) { + msg_ret = FALSE; + goto done; + } + + for (i = 0; i < folder_list.nCount; i++) { + p_folder = folder_list.msg_struct_info[i]; + memset(folder_name, 0x00, BT_MAP_MSG_INFO_MAX); + + ret = msg_get_str_value(p_folder, MSG_FOLDER_INFO_NAME_STR, + folder_name, BT_MAP_MSG_INFO_MAX); + if (ret != MSG_SUCCESS) + continue; + + DBG("%d. %s", i, folder_name); + if (g_strstr_len(folder_name, -1, BT_MAP_MSG_TEMPLATE) || + g_strstr_len(folder_name, -1, "CBMSGBOX") || + g_strstr_len(folder_name, -1, "SPAMBOX")) + continue; + + if (!g_ascii_strncasecmp(folder_name, BT_MAP_SENT_FOLDER_NAME, + strlen(BT_MAP_SENT_FOLDER_NAME))) { + memset(folder_name, 0, sizeof(folder_name)); + g_strlcpy(folder_name, BT_MAP_SENT_FOLDER_NAME, + sizeof(folder_name)); + folders[BT_MSG_SENT][BT_MSG_SOURCE_SMS] = TRUE; + DBG("SENT"); + } else if (!g_ascii_strcasecmp(folder_name, "INBOX")) { + folders[BT_MSG_INBOX][BT_MSG_SOURCE_SMS] = TRUE; + DBG("INBOX"); + } else if (!g_ascii_strcasecmp(folder_name, "OUTBOX")) { + folders[BT_MSG_OUTBOX][BT_MSG_SOURCE_SMS] = TRUE; + DBG("OUTBOX"); + } else if (!g_ascii_strcasecmp(folder_name, "DRAFT")) { + folders[BT_MSG_DRAFT][BT_MSG_SOURCE_SMS] = TRUE; + DBG("DRAFT"); + } else if (!g_ascii_strcasecmp(folder_name, "DELETED")) { + folders[BT_MSG_DELETED][BT_MSG_SOURCE_SMS] = TRUE; + DBG("DELETED"); + } + } + +done: + + if (folder_list.msg_struct_info) + msg_release_list_struct(&folder_list); + + FN_END; + return msg_ret; +} + +gboolean _bt_map_sms_set_read_status(int msg_id, gboolean read_status) +{ + FN_START; + msg_error_t msg_err; + + msg_err = msg_update_read_status(g_msg_handle, msg_id, + read_status); + if (msg_err != MSG_SUCCESS) { + ERR("Failed to Set Read Status"); + return FALSE; + + } + FN_END; + return TRUE; +} + + +static gchar *__bt_get_sms_folder_name(int id) +{ + FN_START; + int ret; + int i; + int folder_id; + gboolean path_found = FALSE; + char folder_name[BT_MAP_MSG_INFO_MAX] = {0,}; + + msg_struct_list_s folder_list = {0,}; + msg_struct_t p_folder; + + ret = msg_get_folder_list(g_msg_handle, &folder_list); + if (ret != MSG_SUCCESS) + return g_strdup("TELECOM/MSG"); + + if (folder_list.msg_struct_info == NULL) + return g_strdup("TELECOM/MSG"); + + for (i = 0; i < folder_list.nCount; i++) { + p_folder = folder_list.msg_struct_info[i]; + + ret = msg_get_int_value(p_folder, + MSG_FOLDER_INFO_ID_INT, + &folder_id); + if (ret != MSG_SUCCESS) + break; + DBG("folder_id %d, id = %d", folder_id, id); + if (folder_id == id) { + ret = msg_get_str_value(p_folder, + MSG_FOLDER_INFO_NAME_STR, + folder_name, BT_MAP_MSG_INFO_MAX); + if (ret != MSG_SUCCESS) + break; + + path_found = TRUE; + DBG_SECURE("folder_name %s", folder_name); + break; + } + } + + if (folder_list.msg_struct_info) { + ret = msg_release_list_struct(&folder_list); + ERR("Err %d", ret); + } + + FN_END; + if (path_found != TRUE) + return g_strdup("TELECOM/MSG"); + else + return g_strdup_printf("TELECOM/MSG/%s", folder_name); +} + +gboolean _bt_map_set_sms_delete_status(int msg_id, gboolean delete_status) +{ + FN_START; + int folder_id; + int del_folder_id; + int err; + gchar *folder_name = NULL; + guint64 map_id; + msg_struct_t msg = NULL; + msg_struct_t send_opt = NULL; + + + if (msg_id == -1) + goto fail; + + if (g_msg_handle == NULL) + goto fail; + + msg = msg_create_struct(MSG_STRUCT_MESSAGE_INFO); + if (msg == NULL) + goto fail; + + send_opt = msg_create_struct(MSG_STRUCT_SENDOPT); + if (send_opt == NULL) + goto fail; + + err = msg_get_message(g_msg_handle, + (msg_message_id_t)msg_id, + msg, send_opt); + if (err != MSG_SUCCESS) + goto fail; + + err = msg_get_int_value(msg, MSG_MESSAGE_FOLDER_ID_INT, + &folder_id); + if (err != MSG_SUCCESS) + goto fail; + + folder_name = __bt_get_sms_folder_name(folder_id); + del_folder_id = __bt_get_sms_folder_id(BT_MAP_DELETED_FOLDER_NAME); + map_id = _bt_validate_uid(msg_id, BT_MAP_ID_SMS); + + DBG("msg_id = %d, delete_status = %d\n", msg_id, delete_status); + + if (del_folder_id == -1) { + ERR("Delete folder not present"); + if (delete_status == TRUE) { + err = msg_delete_message(g_msg_handle, msg_id); + if (err != MSG_SUCCESS) + goto fail; + } + } else { + if (delete_status == TRUE) { + err = msg_move_msg_to_folder(g_msg_handle, msg_id, del_folder_id); + if (err == MSG_SUCCESS) { + _bt_mns_client_event_notify("MessageShift", + map_id, + "TELECOM/MSG/DELETED", + folder_name, + "SMS_GSM"); + } + } else { + if (folder_id != del_folder_id) { + DBG("Message not in delete folder"); + goto fail; + } + + err = msg_move_msg_to_folder(g_msg_handle, msg_id, MSG_INBOX_ID); + if (err == MSG_SUCCESS) { + _bt_mns_client_event_notify("MessageShift", + map_id, + "TELECOM/MSG/INBOX", + "TELECOM/MSG/DELETED", + "SMS_GSM"); + } + } + } + + g_free(folder_name); + msg_release_struct(&msg); + msg_release_struct(&send_opt); + + FN_END; + return TRUE; + +fail: + g_free(folder_name); + + msg_release_struct(&msg); + msg_release_struct(&send_opt); + + ERR("Failed to Delete SMS"); + return FALSE; +} + +static msg_error_t __bt_send_sms(int msg_id, msg_struct_t p_msg, msg_struct_t p_send_opt) +{ + FN_START; + msg_error_t err; + msg_struct_t p_req; + + p_req = msg_create_struct(MSG_STRUCT_REQUEST_INFO); + + msg_set_int_value(p_msg, MSG_MESSAGE_ID_INT, msg_id); + msg_set_struct_handle(p_req, MSG_REQUEST_MESSAGE_HND, p_msg); + msg_set_struct_handle(p_req, MSG_REQUEST_SENDOPT_HND, p_send_opt); + + err = msg_sms_send_message(g_msg_handle, p_req); + if (err != MSG_SUCCESS) + ERR("Failed msg_sms_send_message %d", err); + + msg_release_struct(&p_req); + FN_END; + return err; +} + +static int __bt_push_sms(gboolean send, int folder_id, char *body, + GSList *recepients, msg_send_option_t *option) +{ + FN_START; + msg_struct_t msg_info = NULL; + msg_struct_t send_opt = NULL; + msg_error_t err; + + int msg_id = -1; + + msg_info = msg_create_struct(MSG_STRUCT_MESSAGE_INFO); + if (msg_info == NULL) + goto fail; + + err = msg_set_int_value(msg_info, MSG_MESSAGE_TYPE_INT, MSG_TYPE_SMS); + if (err != MSG_SUCCESS) + goto fail; + + if (body) { + err = msg_set_str_value(msg_info, + MSG_MESSAGE_SMS_DATA_STR, + body, strlen(body)); + if (err != MSG_SUCCESS) + goto fail; + } else { + err = msg_set_str_value(msg_info, MSG_MESSAGE_SMS_DATA_STR, + NULL, 0); + if (err != MSG_SUCCESS) + goto fail; + } + + DBG("folder_id %d\n", folder_id); + err = msg_set_int_value(msg_info, MSG_MESSAGE_FOLDER_ID_INT, + folder_id); + if (err != MSG_SUCCESS) + goto fail; + + while (recepients) { + msg_struct_t tmp_addr; + char *address = recepients->data; + if (address == NULL) { + ERR("[ERROR] address is value NULL, skip"); + recepients = g_slist_next(recepients); + continue; + } + + msg_list_add_item(msg_info, + MSG_MESSAGE_ADDR_LIST_HND, &tmp_addr); + + msg_set_int_value(tmp_addr, + MSG_ADDRESS_INFO_RECIPIENT_TYPE_INT, + MSG_RECIPIENTS_TYPE_TO); + + msg_set_str_value(tmp_addr, + MSG_ADDRESS_INFO_ADDRESS_VALUE_STR, + address, strlen(address)); + + recepients = g_slist_next(recepients); + } + + send_opt = msg_create_struct(MSG_STRUCT_SENDOPT); + + err = msg_set_bool_value(send_opt, MSG_SEND_OPT_SETTING_BOOL, true); + if (err != MSG_SUCCESS) + goto fail; + + /* Do not keep a copy + err = msg_set_bool_value(send_opt, MSG_SEND_OPT_KEEPCOPY_BOOL, + option->save_copy); + */ + err = msg_set_bool_value(send_opt, MSG_SEND_OPT_KEEPCOPY_BOOL, + true); + if (err != MSG_SUCCESS) + goto fail; + + msg_id = msg_add_message(g_msg_handle, msg_info, send_opt); + DBG("msg_id = %d\n", msg_id); + + if (send == TRUE) + __bt_send_sms(msg_id, msg_info, send_opt); + + +fail: + msg_release_struct(&msg_info); + msg_release_struct(&send_opt); + FN_END; + return msg_id; +} + +gboolean _bt_map_push_sms_data(struct bmsg_data *bmsg_info, + msg_send_option_t *option, char *folder) +{ + FN_START; + int id = -1; + int folder_id; + char *body = NULL; + GSList *recepients = NULL; + gboolean send = FALSE; + + DBG("Length of Folder String: %d", strlen(bmsg_info->folder)); + if (strlen(bmsg_info->folder) == 0) { + DBG("No Folder Info. Default to OUTBOX"); + bmsg_info->folder = g_strdup(folder); + } + + folder_id = __bt_get_sms_folder_id(bmsg_info->folder); + if (folder_id == -1) + goto done; + + if (folder_id == MSG_OUTBOX_ID) + send = TRUE; + + body = bmsg_get_msg_body(bmsg_info, option->native); + if (body == NULL) + goto done; + + recepients = bmsg_get_msg_recepients(bmsg_info, BT_MAP_ID_SMS); + + id = __bt_push_sms(send, folder_id, body, recepients, option); + if (id == -1) + goto done; + + _bt_update_id(current_push_map_id, id, BT_MAP_ID_SMS); + +done: + g_free(body); + g_slist_free(recepients); + + if (id == -1) { + FN_END; + return FALSE; + } + + FN_END; + return TRUE; +} + + +static char *__bt_prepare_msg_bmseg(msg_struct_t msg_info, gboolean attach, + gboolean transcode) +{ + FN_START; + int ret; + int m_type = MSG_TYPE_SMS; + int folder_id; + int count; + int dptime = 0; + int j; + bool read_status = false; + char msg_body[BT_MAP_MSG_BODY_MAX] = {0,}; + char addr_value[MAX_ADDRESS_VAL_LEN] = {0,}; + char name_value[MAX_DISPLAY_NAME_LEN] = {0,}; + + msg_list_handle_t addr_list = NULL; + msg_struct_t addr_info = NULL; + + GString *msg; + gchar *folder_path = NULL; + gchar *msg_pdu; + + msg = g_string_new(BEGIN_BMSEG); + g_string_append(msg, BMSEG_VERSION); + + ret = msg_get_bool_value(msg_info, MSG_MESSAGE_READ_BOOL, &read_status); + if (ret == MSG_SUCCESS) + INFO("read_status %d\n", read_status); + + if (read_status) + g_string_append_printf(msg, MSEG_STATUS, "READ"); + else + g_string_append_printf(msg, MSEG_STATUS, "UNREAD"); + + ret = msg_get_int_value(msg_info, MSG_MESSAGE_TYPE_INT, &m_type); + if (ret == MSG_SUCCESS) { + INFO("m_type %d\n", m_type); + g_string_append_printf(msg, MSEG_TYPE, "SMS_GSM"); + } + + ret = msg_get_int_value(msg_info, MSG_MESSAGE_FOLDER_ID_INT, + &folder_id); + if (ret == MSG_SUCCESS) { + DBG("folder_id %d\n", folder_id); + + folder_path = __bt_get_sms_folder_name(folder_id); + g_string_append_printf(msg, FOLDER_PATH, folder_path); + } + + ret = msg_get_list_handle(msg_info, MSG_MESSAGE_ADDR_LIST_HND, + (void **)&addr_list); + if (ret == MSG_SUCCESS) { + count = msg_list_length(addr_list); + DBG("count %d \n", count); + + if (count > 0) { + addr_info = (msg_struct_t)msg_list_nth_data(addr_list, + 0); + + msg_get_str_value(addr_info, + MSG_ADDRESS_INFO_ADDRESS_VALUE_STR, + addr_value, MAX_ADDRESS_VAL_LEN); + DBG_SECURE("addr_value %s\n", addr_value); + msg_get_str_value(addr_info, + MSG_ADDRESS_INFO_DISPLAYNAME_STR, + name_value, MAX_DISPLAY_NAME_LEN); + if (!strlen(name_value)) + g_stpcpy(name_value, addr_value); + + DBG_SECURE("name_value %s\n", name_value); + + g_string_append_printf(msg, VCARD, name_value, + addr_value); + } + } + + g_string_append(msg, BEGIN_BENV); + g_string_append(msg, BEGIN_BBODY); + + if (transcode) { + g_string_append_printf(msg, CHARSET, "UTF-8"); + + + ret = msg_get_str_value(msg_info, + MSG_MESSAGE_SMS_DATA_STR, + msg_body, BT_MAP_MSG_BODY_MAX); + if (ret == MSG_SUCCESS) { + g_string_append_printf(msg, LENGTH, strlen(msg_body)); + g_string_append_printf(msg, MSG_BODY, msg_body); + } + } else { + g_string_append_printf(msg, ENCODING, "G-7BIT"); + g_string_append_printf(msg, CHARSET, "native"); + + msg_get_int_value(msg_info, + MSG_MESSAGE_DISPLAY_TIME_INT, &dptime); + + ret = msg_get_str_value(msg_info, MSG_MESSAGE_SMS_DATA_STR, + msg_body, BT_MAP_MSG_BODY_MAX); + if (ret == MSG_SUCCESS) { + int msg_pdu_len = 0; + msg_pdu = __bt_get_sms_pdu_from_msg_data(addr_value, + msg_body, dptime, + &msg_pdu_len); + if (msg_pdu) { + DBG("msg_pdu_len = %d", msg_pdu_len); + + g_string_append_printf(msg, LENGTH, msg_pdu_len); + g_string_append(msg, MSG_BODY_BEGIN); + for (j = 0; j < msg_pdu_len; j++) + g_string_append_printf(msg, "%02x", + msg_pdu[j]); + + g_string_append(msg, MSG_BODY_END); + g_free(msg_pdu); + } + } + } + + g_string_append(msg, END_BBODY); + g_string_append(msg, END_BENV); + g_string_append(msg, END_BMSEG); + g_free(folder_path); + + FN_END; + return g_string_free(msg, FALSE); +} + +gboolean _bt_map_get_sms_message(int message_id, gboolean attach, + gboolean transcode, gboolean first_request, gchar **bmseg) +{ + FN_START; + msg_error_t msg_err; + msg_struct_t msg = NULL; + msg_struct_t send_opt = NULL; + + DBG("message_id %d \n", message_id); + DBG("attach %d \n", attach); + DBG("transcode %d \n", transcode); + DBG("first_request %d \n", first_request); + + if (g_msg_handle == NULL) + goto fail; + + msg = msg_create_struct(MSG_STRUCT_MESSAGE_INFO); + if (!msg) + goto fail; + + send_opt = msg_create_struct(MSG_STRUCT_SENDOPT); + if (!send_opt) + goto fail; + + msg_err = msg_get_message(g_msg_handle, + (msg_message_id_t)message_id, + msg, send_opt); + if (msg_err != MSG_SUCCESS) + goto fail; + + *bmseg = __bt_prepare_msg_bmseg(msg, attach, transcode); + msg_release_struct(&msg); + msg_release_struct(&send_opt); + + FN_END; + return TRUE; + +fail: + + if (msg) + msg_release_struct(&msg); + + if (send_opt) + msg_release_struct(&send_opt); + + ERR("Unable to Get SMS Message"); + return FALSE; +} + +static char *__bt_get_truncated_utf8_string(char *src) +{ + FN_START; + char *p = src; + char *next; + char dest[BT_MAP_SUBJECT_MAX_LEN] = {0,}; + int count; + int i = 0; + + if (src == NULL) + return NULL; + + while (*p != '\0' && i < sizeof(dest)) { + next = g_utf8_next_char(p); + count = next - p; + + while (count > 0 && ((i + count) < sizeof(dest))) { + dest[i++] = *p; + p++; + count --; + } + p = next; + } + + FN_END; + return g_strdup(dest); +} + + +static message_info_t *__bt_message_info_get(msg_struct_t msg_struct_handle, + guint8 subject_len) +{ + FN_START; + message_info_t *msg_info = NULL; + int ret; + int msg_id; + guint64 uid; + time_t dptime; + int m_type = 0; + int data_size; + int priority; + int direction_type; + int count; + bool protect_status = 0; + bool read_status = 0; + + char msg_handle[BT_MAP_MSG_HANDLE_MAX] = {0,}; + char msg_datetime[BT_MAP_TIMESTAMP_MAX_LEN] = {0,}; + char msg_size[5] = {0,}; + char msg_body[BT_MAP_MSG_BODY_MAX] = {0,}; + char addr_value[MAX_ADDRESS_VAL_LEN] = {0,}; + char name_value[MAX_DISPLAY_NAME_LEN] = {0,}; + + msg_info = g_new0(message_info_t, 1); + msg_info->text = FALSE; + msg_info->protect = FALSE; + msg_info->read = FALSE; + msg_info->priority = FALSE; + + msg_struct_t msg = NULL; + msg_struct_t send_opt = NULL; + msg_list_handle_t addr_list = NULL; + msg_struct_t addr_info = NULL; + + ret = msg_get_int_value(msg_struct_handle, MSG_MESSAGE_ID_INT, &msg_id); + if (ret != MSG_SUCCESS) { + ERR("Could not get Message ID"); + } + + uid = _bt_add_id(msg_id, BT_MAP_ID_SMS); + snprintf(msg_handle, sizeof(msg_handle), "%llx", uid); + DBG("HANDLE: %s, MAP Id: %d, MSG ID:%d", msg_handle, uid, msg_id); + msg_info->handle = g_strdup(msg_handle); + + msg = msg_create_struct(MSG_STRUCT_MESSAGE_INFO); + if (msg == NULL) + goto next; + + send_opt = msg_create_struct(MSG_STRUCT_SENDOPT); + if (send_opt == NULL) + goto next; + + ret = msg_get_message(g_msg_handle, + (msg_message_id_t)msg_id, + msg, send_opt); + if (ret != MSG_SUCCESS) { + DBG("ret = %d\n", ret); + goto next; + } + + ret = msg_get_list_handle(msg, MSG_MESSAGE_ADDR_LIST_HND, + (void **)&addr_list); + if (ret != MSG_SUCCESS) { + DBG("ret = %d\n", ret); + goto next; + } + + count = msg_list_length(addr_list); + + if (count != 0) { + addr_info = (msg_struct_t)msg_list_nth_data(addr_list, 0); + + ret = msg_get_str_value(addr_info, + MSG_ADDRESS_INFO_ADDRESS_VALUE_STR, + addr_value, MAX_ADDRESS_VAL_LEN); + if (ret == MSG_SUCCESS) + DBG_SECURE("addr_value %s\n", addr_value); + + ret = msg_get_str_value(addr_info, + MSG_ADDRESS_INFO_DISPLAYNAME_STR, + name_value, MAX_DISPLAY_NAME_LEN); + + if (ret == MSG_SUCCESS) + DBG_SECURE("name_value %s\n", name_value); + + if (!strlen(name_value)) + g_stpcpy(name_value, addr_value); + + DBG_SECURE("name_value %s\n", name_value); + } + + ret = msg_get_int_value(msg, MSG_MESSAGE_DIRECTION_INT, + &direction_type); + if (ret != MSG_SUCCESS) + goto next; + + if (direction_type == MSG_DIRECTION_TYPE_MT) { + msg_info->sender_name = g_strdup(name_value); + msg_info->sender_addressing = g_strdup(addr_value); + msg_info->recipient_name = g_strdup("Unknown"); + msg_info->recipient_addressing = g_strdup("0000"); + } else { + msg_info->sender_name = g_strdup("Unknown"); + msg_info->sender_addressing = g_strdup("0000"); + msg_info->recipient_name = g_strdup(name_value); + msg_info->recipient_addressing = g_strdup(addr_value); + } + +next: + msg_release_struct(&msg); + msg_release_struct(&send_opt); + + ret = msg_get_int_value(msg_struct_handle, + MSG_MESSAGE_DISPLAY_TIME_INT, &dptime); + if (ret == MSG_SUCCESS) { + _get_msg_timestamp(&dptime, msg_datetime); + } + DBG("Got date time: %s", msg_datetime); + + msg_info->datetime = g_strdup(msg_datetime); + msg_info->time = dptime; // for sorting + + ret = msg_get_int_value(msg_struct_handle, MSG_MESSAGE_TYPE_INT, + &m_type); + if (ret == MSG_SUCCESS) { + DBG("m_type %d\n", m_type); + } + + msg_info->type = g_strdup("SMS_GSM"); + + ret = msg_get_str_value(msg_struct_handle, + MSG_MESSAGE_SMS_DATA_STR, msg_body, + BT_MAP_MSG_BODY_MAX); + if (ret == MSG_SUCCESS) { + DBG_SECURE("SMS subject %s", msg_body); + if (strlen(msg_body)) { + char *subject; + msg_info->text = TRUE; + subject = __bt_get_truncated_utf8_string(msg_body); + msg_info->subject = g_strndup(subject, subject_len); + g_free(subject); + } + } + + ret = msg_get_int_value(msg_struct_handle, MSG_MESSAGE_DATA_SIZE_INT, + &data_size); + if (ret == MSG_SUCCESS) + snprintf(msg_size, sizeof(msg_size), "%d", data_size); + + msg_info->size = g_strdup(msg_size); + + msg_info->reception_status = g_strdup("complete"); + msg_info->attachment_size = g_strdup("0"); + + ret = msg_get_bool_value(msg_struct_handle, MSG_MESSAGE_PROTECTED_BOOL, + &protect_status); + if (ret == MSG_SUCCESS) { + if (protect_status) + msg_info->protect = TRUE; + } + + ret = msg_get_bool_value(msg_struct_handle, MSG_MESSAGE_READ_BOOL, + &read_status); + if (ret == MSG_SUCCESS) { + if (read_status) + msg_info->read = TRUE; + } + + ret = msg_get_int_value(msg_struct_handle, MSG_MESSAGE_PRIORITY_INT, + &priority); + if (ret == MSG_SUCCESS) { + if (priority == MSG_MESSAGE_PRIORITY_HIGH) + msg_info->priority = TRUE; + } + + FN_END; + return msg_info; +} + +gboolean _bt_map_get_sms_message_list(gchar *folder, guint16 max, + guint8 subject_len, map_msg_filter_t *filter, + GSList **sms_list, guint64 *count, gboolean *newmsg) +{ + FN_START; + int i = 0; + int ret = 0; + int folder_id = -1; + guint64 local_count; + bool read; + + msg_struct_list_s folder_list = {0,}; + msg_struct_list_s msg_list = {0,}; + msg_struct_t list_cond; + GSList *list = NULL; + int msg_count; + + DBG("Folder:%s Max:%d", folder, max); + if (max == 0) + max = 1024; + + ret = msg_get_folder_list(g_msg_handle, &folder_list); + if (ret != MSG_SUCCESS) + goto fail; + + for (i = 0; i < folder_list.nCount; i++) { + char f_name[BT_MAP_MSG_INFO_MAX] = {0, }; + msg_struct_t p_folder = folder_list.msg_struct_info[i]; + + ret = msg_get_str_value(p_folder, MSG_FOLDER_INFO_NAME_STR, + f_name, BT_MAP_MSG_INFO_MAX); + if (ret != MSG_SUCCESS) + continue; + + if (!g_ascii_strncasecmp(f_name, folder, strlen(folder))) { + ret = msg_get_int_value(p_folder, MSG_FOLDER_INFO_ID_INT, + &folder_id); + if (ret != MSG_SUCCESS) + goto fail; + + DBG("folder_id %d \n", folder_id); + + break; + } + } + + if (folder_id == -1) + goto fail; + + list_cond = msg_create_struct(MSG_STRUCT_MSG_LIST_CONDITION); + ret = msg_set_int_value(list_cond, + MSG_LIST_CONDITION_FOLDER_ID_INT, + folder_id); + if (ret != MSG_SUCCESS) + goto fail; + + ret = msg_set_int_value(list_cond, + MSG_LIST_CONDITION_MSGTYPE_INT, MSG_TYPE_SMS); + if (ret != MSG_SUCCESS) + goto fail; + + ret = msg_get_message_list2(g_msg_handle, list_cond, &msg_list); + + msg_release_struct(&list_cond); + + if (ret != MSG_SUCCESS) + goto fail; + + local_count = (guint64)msg_list.nCount; + DBG("msg_list.nCount: %d, count:%d", msg_list.nCount, local_count); + for (i = 0; i < local_count; i++) { + msg_get_bool_value(msg_list.msg_struct_info[i], + MSG_MESSAGE_READ_BOOL, &read); + if (read == false) { + *newmsg = TRUE; + break; + } + } + + DBG("count = %llx, newmsg = %d, max = %d", local_count, *newmsg, max); + + for (i = 0, msg_count = 0; i < local_count && msg_count < max; i++) { + message_info_t *msg_info; + + msg_info = __bt_message_info_get(msg_list.msg_struct_info[i], + subject_len); + + if (!_bt_verify_read_status(msg_info, filter->read_status) || + !_bt_verify_receiver(msg_info, filter->recipient) || + !_bt_verify_sender(msg_info, filter->originator) || + !_bt_verify_time(msg_info, filter) || + !_bt_filter_priority(msg_info, filter->priority) || + !_bt_validate_msg_data(msg_info)) { + _bt_message_info_free((gpointer)msg_info); + continue; + } + + list = g_slist_append(list, msg_info); + msg_count++; + } + + if (folder_list.msg_struct_info) + ret = msg_release_list_struct(&folder_list); + + if (msg_list.msg_struct_info) + ret = msg_release_list_struct(&msg_list); + + *count = local_count; + *sms_list = list; + FN_END; + return TRUE; + +fail: + if (folder_list.msg_struct_info) + ret = msg_release_list_struct(&folder_list); + + if (msg_list.msg_struct_info) + ret = msg_release_list_struct(&msg_list); + + ERR("Getting SMS List Failed"); + return FALSE; +} + +void _bt_map_stop_sms_service(void) +{ + FN_START; + msg_error_t err = MSG_SUCCESS; + int folder_id; + + folder_id = __bt_get_sms_folder_id(BT_MAP_DELETED_FOLDER_NAME); + if (folder_id != -1) { + err = msg_delete_folder(g_msg_handle, folder_id); + if (err != MSG_SUCCESS) + ERR("Delete folder failed"); + } + + if (g_msg_handle) { + msg_close_msg_handle(&g_msg_handle); + g_msg_handle = NULL; + } + + FN_END; +} + +gboolean _bt_map_start_sms_service(void) +{ + FN_START; + msg_error_t err; + + err = msg_open_msg_handle(&g_msg_handle); + if (err != MSG_SUCCESS) { + ERR("msg_open_msg_handle error = %d\n", err); + return FALSE; + } + + if (__bt_get_sms_folder_id(BT_MAP_DELETED_FOLDER_NAME) == -1) + __bt_add_deleted_folder(); + + err = msg_reg_sms_message_callback(g_msg_handle, + __bluetooth_map_msg_incoming_status_cb, + 0, (void *)BT_MAP_MSG_CB); + if (err != MSG_SUCCESS) { + ERR("msg_reg_sms_message_callback error = %d\n", err); + return FALSE; + } + + err = msg_reg_sent_status_callback(g_msg_handle, + __bluetooth_map_msg_sent_status_cb, + NULL); + if (err != MSG_SUCCESS) { + ERR("msg_reg_sent_status_callback error = %d\n", err); + return FALSE; + } + + FN_END; + return TRUE; +} diff --git a/map-agent/bluetooth_map_sms.h b/map-agent/bluetooth_map_sms.h new file mode 100644 index 0000000..ba5328a --- /dev/null +++ b/map-agent/bluetooth_map_sms.h @@ -0,0 +1,51 @@ +/* + * Bluetooth-agent + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Hocheol Seo + * Syam Sidhardhan + * Chanyeol Park + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef BLUETOOTH_MAP_SMS_H_ +#define BLUETOOTH_MAP_SMS_H_ + +#include +#include "bluetooth_map_types.h" +#include "map_bmessage.h" + +gboolean _bt_map_start_sms_service(void); + +void _bt_map_stop_sms_service(void); + +gboolean _bt_map_sms_get_supported_folders(gboolean folders[FOLDER_COUNT][MSG_TYPES]); + +gboolean _bt_map_get_sms_message_list(gchar *folder, guint16 max, + guint8 subject_len, map_msg_filter_t *filter, + GSList **sms_list, guint64 *count, gboolean *newmsg); + +gboolean _bt_map_get_sms_message(int message_id, gboolean attach, + gboolean transcode, gboolean first_request, gchar **bmseg); + +gboolean _bt_map_set_sms_delete_status(int msg_id, gboolean delete_status); + +gboolean _bt_map_sms_set_read_status(int msg_id, gboolean read_status); + +gboolean _bt_map_push_sms_data(struct bmsg_data *bmsg_info, + msg_send_option_t *option, char *folder); + +#endif /* BLUETOOTH_MAP_SMS_H_ */ diff --git a/map-agent/bluetooth_map_types.h b/map-agent/bluetooth_map_types.h new file mode 100644 index 0000000..4cfd297 --- /dev/null +++ b/map-agent/bluetooth_map_types.h @@ -0,0 +1,100 @@ +/* + * Bluetooth-agent + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Hocheol Seo + * Syam Sidhardhan + * Chanyeol Park + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef BLUETOOTH_MAP_TYPES_H_ +#define BLUETOOTH_MAP_TYPES_H_ + +#define FOLDER_COUNT 5 /* INBOX, OUTBOX, SENT, DRAFT, DELETED*/ +#define MSG_TYPES 2 /* GSM_SMS, EMAIL*/ +#define BT_MAP_SUBJECT_MAX_LEN 50 + +#define FILTER_TYPE_SMS_GSM 0x01 +#define FILTER_TYPE_SMS_CDMA 0x02 +#define FILTER_TYPE_EMAIL 0x04 +#define FILTER_TYPE_MMS 0x08 + +#define FILTER_READ_STATUS_ALL 0x00 +#define FILTER_READ_STATUS_UNREAD 0x01 +#define FILTER_READ_STATUS_READ 0x02 + +#define FILTER_PRIORITY_ALL 0x00 +#define FILTER_PRIORITY_HIGH 0x01 +#define FILTER_PRIORITY_LOW 0x02 + +typedef struct { + char *handle; + char *subject; + char *datetime; + char *sender_name; + char *sender_addressing; + char *recipient_name; + char *recipient_addressing; + char *type; + char *size; + char *reception_status; + char *attachment_size; + char *replyto_addressing; + gboolean text; + gboolean priority; + gboolean read; + gboolean sent; + gboolean protect; + time_t time; /* for sorting */ +} message_info_t; + +typedef enum { + BT_MSG_INBOX = 0, + BT_MSG_SENT, + BT_MSG_OUTBOX, + BT_MSG_DRAFT, + BT_MSG_DELETED +} folders_t; + +typedef enum { + BT_MSG_SOURCE_SMS = 0, + BT_MSG_SOURCE_EMAIL +} source_t; + +typedef enum { + BT_MAP_ID_SMS, + BT_MAP_ID_EMAIL +} bt_msg_t; + +typedef struct { + gboolean save_copy; + gboolean retry_send; + gboolean native; +} msg_send_option_t; + + +typedef struct { + guint32 parameter_mask; + guint8 type; + char *period_begin; + char *period_end; + guint8 read_status; + char *recipient; + char *originator; + guint8 priority; +} map_msg_filter_t; +#endif /* BLUETOOTH_MAP_TYPES_H_ */ diff --git a/map-agent/map_bmessage.c b/map-agent/map_bmessage.c index 87ce5bf..7b38fdb 100644 --- a/map-agent/map_bmessage.c +++ b/map-agent/map_bmessage.c @@ -308,7 +308,59 @@ char *bmsg_get_msg_body(struct bmsg_data *bmsg, gboolean utf) return NULL; } -GSList *bmsg_get_msg_recepients(struct bmsg_data *bmsg) +char *get_line(char *string, int *len) +{ + int i = 0; + while (string[i] != '\n' && string[i] != '\0') + i++; + + *len = i; + return g_strndup(string, i - 1); +} + +gboolean bmsg_parse_msg_body(const char *message, + char **body, char **subject) +{ + FN_START; + DBG("Message: %s", message); + char *temp = (char *)message; + char *line = NULL; + int len; + + *subject = NULL; + *body = NULL; + while ((line = get_line(temp, &len)) != NULL) { + if (!g_ascii_strncasecmp(line, "Date:", strlen("Date:"))) { + //Currently nothing to be done + } else if (!g_ascii_strncasecmp(line, "Subject:", strlen("Subject:"))) { + char *sub = line + strlen("Subject:"); + while (*sub == ' ') + sub++; + DBG("Subject: %s", sub); + *subject = g_strdup(sub); + } else if (!g_ascii_strncasecmp(line, "From:", strlen("From:"))) { + //Currently nothing to be done + } else if (!g_ascii_strncasecmp(line, "To:", strlen("To:"))) { + //Currently nothing to be done + } else { + DBG("BODY: %s", temp); + *body = g_strdup(temp); + g_free(line); + break; + } + + while ((temp[len] == '\r' || temp[len] == '\n') && temp[len] != '\0') + len++; + + temp = temp + len; + + g_free(line); + } + return TRUE; + FN_END; +} + +GSList *bmsg_get_msg_recepients(struct bmsg_data *bmsg, int msg_type) { FN_START; struct benv_data *env_data; @@ -327,12 +379,19 @@ GSList *bmsg_get_msg_recepients(struct bmsg_data *bmsg) while (rvcard != NULL) { k++; - if (rvcard->tel != NULL) { - DBG_SECURE("vcard->tel = %s\n", rvcard->tel); - receiver = g_slist_append(receiver, - rvcard->tel); + if (msg_type == BT_MAP_ID_SMS) { + if (rvcard->tel != NULL) { + DBG_SECURE("vcard->tel = %s\n", rvcard->tel); + receiver = g_slist_append(receiver, + rvcard->tel); + } + } else { + if (rvcard->email != NULL) { + DBG_SECURE("vcard->email = %s\n", rvcard->email); + receiver = g_slist_append(receiver, + rvcard->email); + } } - rvcard = g_slist_nth_data(env_data->recipient_vcard, k); } @@ -600,17 +659,16 @@ struct bmsg_envelope *bmsg_get_envelope_data(gchar **block_data) { FN_START; gchar *sub_block_data; - gchar *benv_block_data; struct bmsg_envelope *envelope_data; struct benv_data *rec_data; envelope_data = g_new0(struct bmsg_envelope, 1); - benv_block_data = bmsg_get_parse_sub_block(block_data, "BENV"); - sub_block_data = benv_block_data; + sub_block_data = bmsg_get_parse_sub_block(block_data, "BENV"); while (sub_block_data) { - + char *next_sub_block_data; + char *save_sub_block_data = sub_block_data; rec_data = bmsg_get_env_encapsulation_data(&sub_block_data); while (rec_data) { @@ -621,12 +679,12 @@ struct bmsg_envelope *bmsg_get_envelope_data(gchar **block_data) rec_data = bmsg_get_env_encapsulation_data( &sub_block_data); } - g_free(benv_block_data); - benv_block_data = bmsg_get_parse_sub_block(&sub_block_data, - "BENV"); - sub_block_data = benv_block_data; + next_sub_block_data = bmsg_get_parse_sub_block(&sub_block_data, + "BENV"); + g_free(save_sub_block_data); + sub_block_data = next_sub_block_data; } - g_free(benv_block_data); + g_free(sub_block_data); FN_END; return envelope_data; } diff --git a/map-agent/map_bmessage.h b/map-agent/map_bmessage.h index 860f86f..2e9e945 100644 --- a/map-agent/map_bmessage.h +++ b/map-agent/map_bmessage.h @@ -67,7 +67,9 @@ struct bmsg_data { struct bmsg_data * bmsg_parse(gchar *buf); char *bmsg_get_msg_folder(struct bmsg_data *bmsg); char *bmsg_get_msg_body(struct bmsg_data *bmsg, gboolean utf); -GSList *bmsg_get_msg_recepients(struct bmsg_data *bmsg); +GSList *bmsg_get_msg_recepients(struct bmsg_data *bmsg, int msg_type); +gboolean bmsg_parse_msg_body(const char *message, + char **body, char **subject); void bmsg_free_bmsg(struct bmsg_data *bmsg); #ifdef __cplusplus diff --git a/packaging/bluetooth-agent.spec b/packaging/bluetooth-agent.spec index df33492..ae3d347 100644 --- a/packaging/bluetooth-agent.spec +++ b/packaging/bluetooth-agent.spec @@ -25,6 +25,7 @@ BuildRequires: pkgconfig(msg-service) %endif BuildRequires: pkgconfig(capi-system-info) BuildRequires: pkgconfig(dbus-glib-1) +BuildRequires: pkgconfig(email-service) BuildRequires: pkgconfig(tapi) BuildRequires: pkgconfig(dlog) BuildRequires: pkgconfig(vconf) @@ -32,6 +33,7 @@ BuildRequires: pkgconfig(appsvc) BuildRequires: pkgconfig(capi-appfw-application) BuildRequires: pkgconfig(capi-media-image-util) BuildRequires: pkgconfig(libexif) +BuildRequires: pkgconfig(gio-2.0) BuildRequires: cmake Requires: security-config @@ -81,6 +83,15 @@ mkdir -p %{buildroot}%{_unitdir}/multi-user.target.wants #install -m 0644 packaging/bluetooth-ag-agent.service %{buildroot}%{_unitdir}/ #ln -s ../bluetooth-ag-agent.service %{buildroot}%{_unitdir}/multi-user.target.wants/bluetooth-ag-agent.service #%endif +%if 0%{?sec_product_feature_bt_map_server_enable} +install -D -m 0644 packaging/bluetooth-map-agent.service %{buildroot}%{_libdir}/systemd/user/bluetooth-map-agent.service +%endif + + +%post +%if 0%{?sec_product_feature_bt_map_server_enable} +ln -sf %{_libdir}/systemd/user/bluetooth-map-agent.service %{_sysconfdir}/systemd/default-extra-dependencies/ignore-units.d/ +%endif %files %manifest %{name}.manifest -- 2.7.4