SVACE issue fix
[platform/core/messaging/msg-service.git] / utils / MsgVMessage.cpp
index 862502d..39ba518 100755 (executable)
 /*
-* Copyright 2012-2013  Samsung Electronics Co., Ltd
-*
-* Licensed under the Flora License, Version 1.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://floralicense.org
-*
-* 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.
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd. All rights reserved
+ *
+ * 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 <glib.h>
+#include <errno.h>
+#include <ctype.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <unicode/ucnv.h>
+#include <unicode/ustring.h>
+
 #include <VMessage.h>
 #include <VCard.h>
 #include <time.h>
 
 #include "MsgMmsTypes.h"
-
+#include "MsgContact.h"
 #include "MsgDebug.h"
 #include "MsgUtilFile.h"
 #include "MsgCppTypes.h"
 #include "MsgVMessage.h"
+#include "MsgMmsMessage.h"
+#include "MsgSerialize.h"
+
+#define VMSG_INIT_LENGTH 1024
+#define VMSG_ITEM_LENGTH 1024
+#define MSGSVC_VMSG_FOLDING_LIMIT 75
+
+#define SMART_STRDUP(src) (src && *src)?strdup(src):NULL
+#define SAFE_STR(src) (src)?src:""
+
+#define MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, str) do { \
+       if ((len = __msgsvc_vmsg_append_str(buf, buf_size, len, str, false)) < 0) { \
+               MSG_ERR("__msgsvc_vmsg_append_str() Failed"); \
+               return MSG_ERR_MEMORY_ERROR; \
+       } \
+} while (0)
+
+#define MSGSVC_VMSG_APPEND_STR_FREE(buf, buf_size, len, str) do { \
+       if ((len = __msgsvc_vmsg_append_str(buf, buf_size, len, str, false)) < 0) { \
+               MSG_ERR("__msgsvc_vmsg_append_str() Failed"); \
+               if (str) \
+                       free(str); \
+               return MSG_ERR_MEMORY_ERROR; \
+       } \
+} while (0)
+
+#define MSGSVC_VMSG_APPEND_CONTENT_STR(buf, buf_size, len, content) do { \
+       if ((len = __msgsvc_vmsg_append_str(buf, buf_size, len, content, true)) < 0) { \
+               MSG_ERR("__msgsvc_vmsg_append_str() Failed"); \
+               return MSG_ERR_MEMORY_ERROR; \
+       } \
+} while (0)
+
+
+#define MSGSVC_VMSG_APPEND_CONTENT(buf, buf_size, len, content) do { \
+       MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, ";CHARSET=UTF-8"); \
+       MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, ":"); \
+       MSGSVC_VMSG_APPEND_CONTENT_STR(buf, buf_size, len, content); \
+       MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF); \
+} while (0)
+
+enum {
+       CTSVC_VCARD_VER_NONE,
+       CTSVC_VCARD_VER_2_1,
+       CTSVC_VCARD_VER_3_0,
+       CTSVC_VCARD_VER_4_0,
+};
+
+enum {
+       MSGSVC_VMSG_VER_NONE,
+       MSGSVC_VMSG_VER_1_1,
+       MSGSVC_VMSG_VER_3_0
+};
+
+
+enum {
+        /* vMessage */
+       VMSG_VALUE_NONE = 0,
+       BEGIN_VMSG = 1,
+       VERSION_VMSG = 2,
+       BEGIN_VCARD = 3,
+       VERSION_VCARD = 4,
+       END_VCARD = 5,
+       BEGIN_VENV = 6,
+       BEGIN_VBODY = 7,
+       END_VBODY = 8,
+       END_VENV = 9,
+       END_VMSG = 10,
+
+       FNAME_VCARD = 11 ,
+       NAME_VCARD = 12,
+       TEL_VCARD = 13,
+       TEL_VCARD_CELL = 14,
+
+       DATE_VMSG = 15,
+       SUBJECT_VMSG = 16,
+
+       FNAME_UTF8_VCARD = 17,
+       NAME_UTF8_VCARD = 18,
+
+       /* Encodings */
+       VMSG_ATTR_ENCODING_QP = 19,
+       VMSG_ATTR_ENCODING_BASE64_V21 = 20,
+       VMSG_ATTR_ENCODING_BASE64_V30 = 21,
+
+       /* Message type indication */
+       VMSG_INDICATION_MESSAGE_TYPE = 22,
+       VMSG_INDICATION_MESSAGE_TYPE_INET = 23,
+       VMSG_INDICATION_MESSAGE_TYPE_MSG = 24,
+
+       /* Read status indication */
+       VMSG_INDICATION_READ_STATUS = 25,
+       VMSG_INDICATION_READ_STATUS_READ = 26,
+       VMSG_INDICATION_READ_STATUS_UNREAD = 27,
+
+       /* Mailbox status indication */
+       VMSG_INDICATION_MSG_BOX = 28,
+       VMSG_INDICATION_MSG_BOX_SENT = 29,
+       VMSG_INDICATION_MSG_BOX_INBOX = 30,
+       VMSG_INDICATION_MSG_BOX_DRAFT = 31,
+
+       /* Character set */
+       VMSG_ATTR_CHARSET_PROPERTY = 32,
+
+       /* Language */
+       VMSG_ATTR_LANGUAGE_PROPERTY = 33,
+       VMSG_DATA_SEPARATOR = 34,
+
+       VMSG_BODY_PROPERTY_DATE = 35,
+       VMSG_BODY_PROPERTY_SUBJECT = 36,
+       VMSG_BODY_PROPERTY_FROM = 37,
+       VMSG_BODY_PROPERTY_TO = 38,
+
+       KEY_BODY = 39,
+       KEY_DATE = 40,
+
+       /* DECODER */
+       VMSG_VCARD_TEL = 41,
+       VMSG_MSG_BEGIN = 42,
+       VMSG_MSG_END = 43,
+       VMSG_MAXIMUM_VALUE = 44,
+};
+
+static const char *content_name[VMSG_MAXIMUM_VALUE+1] = {0};
+const char *MSGSVC_CRLF = "\r\n";
+bool needCharset = false;
+
+static void __msgsvc_vmsg_initial(void)
+{
+       if (NULL == *content_name) {
+               /* vMessage */
+               content_name[BEGIN_VMSG] = "BEGIN:VMSG";
+               content_name[VERSION_VMSG] = "VERSION:1.1";
+               content_name[BEGIN_VCARD] = "BEGIN:VCARD";
+               content_name[VERSION_VCARD] = "VERSION:2.1";
+               content_name[END_VCARD] = "END:VCARD";
+               content_name[BEGIN_VENV] = "BEGIN:VENV";
+               content_name[BEGIN_VBODY] = "BEGIN:VBODY";
+               content_name[END_VBODY] = "END:VBODY";
+               content_name[END_VENV] = "END:VENV";
+               content_name[END_VMSG] = "END:VMSG";
+
+               content_name[FNAME_VCARD] = "FN:";
+               content_name[NAME_VCARD] = "N:";
+               content_name[TEL_VCARD] = "TEL;";
+               content_name[TEL_VCARD_CELL] = "CELL:";
+
+               content_name[DATE_VMSG] = "Date:";
+               content_name[SUBJECT_VMSG] = "Subject:";
+
+               content_name[FNAME_UTF8_VCARD] = "FN;CHARSET=UTF-8:";
+               content_name[NAME_UTF8_VCARD] = "N;CHARSET=UTF-8:";
+
+               /* Encodings */
+               content_name[VMSG_ATTR_ENCODING_QP] = "ENCODING=QUOTED-PRINTABLE";
+               content_name[VMSG_ATTR_ENCODING_BASE64_V21] = "ENCODING=BASE64";
+               content_name[VMSG_ATTR_ENCODING_BASE64_V30] = "ENCODING=b";
+
+               /* Message type indication */
+               content_name[VMSG_INDICATION_MESSAGE_TYPE] = "X-IRMC-TYPE";
+               content_name[VMSG_INDICATION_MESSAGE_TYPE_INET] = "INET";
+               content_name[VMSG_INDICATION_MESSAGE_TYPE_MSG] = "MSG";
+
+               /* Read status indication */
+               content_name[VMSG_INDICATION_READ_STATUS] = "X-IRMC-STATUS";
+               content_name[VMSG_INDICATION_READ_STATUS_READ] = "READ";
+               content_name[VMSG_INDICATION_READ_STATUS_UNREAD] =  "UNREAD";
+
+               /* Mailbox status indication */
+               content_name[VMSG_INDICATION_MSG_BOX] = "X-IRMC-BOX";
+               content_name[VMSG_INDICATION_MSG_BOX_SENT] = "SENT";
+               content_name[VMSG_INDICATION_MSG_BOX_INBOX] = "INBOX";
+               content_name[VMSG_INDICATION_MSG_BOX_DRAFT] =  "DRAFT";
+
+               /* Character set */
+               content_name[VMSG_ATTR_CHARSET_PROPERTY] = "CHARSET";
+
+               /* Language */
+               content_name[VMSG_ATTR_LANGUAGE_PROPERTY] =  "LANGUAGE";
+               content_name[VMSG_DATA_SEPARATOR] = ":";
+
+               content_name[VMSG_BODY_PROPERTY_DATE] = "Date";
+               content_name[VMSG_BODY_PROPERTY_SUBJECT] = "Subject";
+               content_name[VMSG_BODY_PROPERTY_FROM] = "From";
+               content_name[VMSG_BODY_PROPERTY_TO] = "To";
+
+               content_name[KEY_BODY] = "body";
+               content_name[KEY_DATE] = "date";
+
+               content_name[VMSG_VCARD_TEL] = "TEL";
+               content_name[VMSG_MSG_BEGIN] = "BEGIN";
+               content_name[VMSG_MSG_END] = "END";
+               content_name[VMSG_MAXIMUM_VALUE] = "MAX";
+       }
+};
+
+static int __msgsvc_vmsg_append_str(char **buf, int *buf_size, int len, const char *str, bool need_conversion)
+{
+       int len_temp = 0;
+       char *tmp = NULL;
+       const char *safe_str = SAFE_STR(str);
+       int str_len = 0;
+       bool need_realloc = false;
+
+       str_len = strlen(safe_str);
+       while ((*buf_size-len) < (str_len+1)) {
+               *buf_size = *buf_size * 2;
+               need_realloc = true;
+       }
+
+       if (need_realloc) {
+               if (NULL == (tmp = (char *)realloc(*buf, *buf_size)))
+                       return -1;
+               else
+                       *buf = tmp;
+       }
+
+       if (need_conversion) {
+               const char *s = safe_str;
+               char *r = (char *)(*buf+len);
+
+               while (*s) {
+                       switch ((unsigned int)*s) {
+                       case '\r':
+                               if (*(s+1) && '\n' == *(s+1)) {
+                                       s++;
+                                       *r = '\\';
+                                       r++;
+                                       *r = 'n';
+                               } else {
+                                       *r = *s;
+                               }
+                               break;
+                       case '\n':
+                               *r = '\\';
+                               r++;
+                               str_len++;
+                               if (*buf_size < str_len+len+1) {
+                                       *buf_size = *buf_size * 2;
+                                       if (NULL == (tmp = (char *)realloc(*buf, *buf_size))) {
+                                               return -1;
+                                       } else {
+                                               int pos_temp = r-(*buf+len);
+                                               *buf = tmp;
+                                               r = (char *)(*buf+len+pos_temp);
+                                       }
+                               }
+                               *r = 'n';
+                               break;
+                       case ';':
+                       case ':':
+                       case ',':
+                       case '<':
+                       case '>':
+                       case '\\':
+                               *r = '\\';
+                               r++;
+                               str_len++;
+                               if (*buf_size < str_len+len+1) {
+                                       *buf_size = *buf_size * 2;
+                                       if (NULL == (tmp = (char *)realloc(*buf, *buf_size))) {
+                                               return -1;
+                                       } else {
+                                               int pos_temp = r-(*buf+len);
+                                               *buf = tmp;
+                                               r = (char *)(*buf+len+pos_temp);
+                                       }
+                               }
+                               *r = *s;
+                               break;
+                       case 0xA1:
+                               if (*(s+1) && 0xAC == *(s+1)) { /* en/em backslash */
+                                       *r = '\\';
+                                       r++;
+                                       str_len++;
+                                       if (*buf_size < str_len+len+1) {
+                                               *buf_size = *buf_size * 2;
+                                               if (NULL == (tmp = (char *)realloc(*buf, *buf_size))) {
+                                                       return -1;
+                                               } else {
+                                                       int pos_temp = r-(*buf+len);
+                                                       *buf = tmp;
+                                                       r = (char *)(*buf+len+pos_temp);
+                                               }
+                                       }
+
+                                       *r = *s;
+                                       r++;
+                                       s++;
+                                       if (*buf_size < str_len+len+1) {
+                                               *buf_size = *buf_size * 2;
+                                               if (NULL == (tmp = (char *)realloc(*buf, *buf_size))) {
+                                                       return -1;
+                                               } else {
+                                                       int pos_temp = r-(*buf+len);
+                                                       *buf = tmp;
+                                                       r = (char *)(*buf+len+pos_temp);
+                                               }
+                                       }
+                                       *r = *s;
+                               } else {
+                                       *r = *s;
+                               }
+                               break;
+                       case 0x81:
+                               if (*(s+1) && 0x5F == *(s+1)) { /* en/em backslash */
+                                       *r = '\\';
+                                       r++;
+                                       str_len++;
+                                       if (*buf_size < str_len+len+1) {
+                                               *buf_size = *buf_size * 2;
+                                               if (NULL == (tmp = (char *)realloc(*buf, *buf_size))) {
+                                                       return -1;
+                                               } else {
+                                                       int pos_temp = r-(*buf+len);
+                                                       *buf = tmp;
+                                                       r = (char *)(*buf+len+pos_temp);
+                                               }
+                                       }
+
+                                       *r = *s;
+                                       r++;
+                                       s++;
+                                       if (*buf_size < str_len+len+1) {
+                                               *buf_size = *buf_size * 2;
+                                               if (NULL == (tmp = (char *)realloc(*buf, *buf_size))) {
+                                                       return -1;
+                                               } else {
+                                                       int pos_temp = r-(*buf+len);
+                                                       *buf = tmp;
+                                                       r = (char *)(*buf+len+pos_temp);
+                                               }
+                                       }
+                                       *r = *s;
+                               } else {
+                                       *r = *s;
+                               }
+                               break;
+                       default:
+                               *r = *s;
+                               break;
+                       }
+                       r++;
+                       s++;
+               }
+               len_temp = str_len;
+       } else {
+               len_temp = snprintf(*buf+len, *buf_size-len+1, "%s", safe_str);
+       }
+       len += len_temp;
+       return len;
+}
 
 
 /*==================================================================================================
 #define INSERT_VMSG_OBJ pObject = (VObject*)calloc(1, sizeof(VObject));        \
                                       if ( !pObject )\
 {\
-   vmsg_free_vtree_memory( pMessage );\
-   return false;\
+   vmsg_free_vtree_memory(pMessage);\
+   return NULL;\
 }\
 if (pMessage->pTop == NULL)\
 {\
@@ -48,8 +409,8 @@ pMessage->pCur = pObject;
 #define INSERT_VBODY_OBJ pObject = (VObject*)calloc(1, sizeof(VObject));       \
                                       if ( !pObject )\
 {\
-   vmsg_free_vtree_memory( pMessage );\
-   return false;\
+   vmsg_free_vtree_memory(pMessage);\
+   return NULL;\
 }\
 if (pBody->pTop == NULL)\
 {\
@@ -65,8 +426,8 @@ pBody->pCur = pObject;
 #define INSERT_VCARD_OBJ pObject = (VObject*)calloc(1, sizeof(VObject));       \
                                       if ( !pObject )\
 {\
-   vmsg_free_vtree_memory( pMessage );\
-   return false;\
+   vmsg_free_vtree_memory(pMessage);\
+   return NULL;\
 }\
 if (pCard->pTop == NULL)\
 {\
@@ -82,20 +443,545 @@ pCard->pCur = pObject;
 #define INSERT_PARAM  param = (VParam*)calloc(1, sizeof(VParam));\
                              if (!param)\
 {\
-   vmsg_free_vtree_memory( pMessage );\
+   vmsg_free_vtree_memory(pMessage);\
    if (pObject != NULL)\
    {\
       free(pObject);\
       pObject = NULL;\
    }\
-   return false;\
+   return NULL;\
 }
 
 
 /*==================================================================================================
                                      FUNCTION IMPLEMENTATION
 ==================================================================================================*/
-char* MsgVMessageAddRecord(MsgDbHandler *pDbHandle, MSG_MESSAGE_INFO_S* pMsg)
+
+char* _convert_tm_to_vdata_str(const struct tm * tm)
+{
+       char str[17] = {0, };
+
+       int wrn = snprintf(str, 17, "%04d%02d%02dT%02d%02d%02dZ",
+               tm->tm_year + 1900,
+               tm->tm_mon +1,
+               tm->tm_mday,
+               tm->tm_hour,
+               tm->tm_min,
+               tm->tm_sec);
+       if(wrn < 0)
+               MSG_DEBUG("snprintf was failed  ");
+
+       return strdup(str);
+}
+
+bool _convert_vdata_str_to_tm(const char* szText, struct tm * tm)
+{
+   if (szText == NULL) return false;
+   if (strlen(szText) < 15) return false;
+   if (szText[8] != 'T') return false;
+
+   char szBuff[8]={0};
+   memset(tm, 0, sizeof(struct tm));
+
+   /* year, month, day */
+   memcpy(szBuff, &(szText[0]), 4);
+   szBuff[4] = '\0';
+   tm->tm_year = atol(szBuff) - 1900;
+   if ((tm->tm_year > 137) || (tm->tm_year < 0))
+      tm->tm_year = 0;
+
+   memcpy(szBuff, &(szText[4]), 2);
+   szBuff[2] = '\0';
+   tm->tm_mon = atol(szBuff)-1;
+   if ((tm->tm_mon > 11) || (tm->tm_mon < 0))
+      tm->tm_mon = 11;
+
+   memcpy(szBuff, &(szText[6]), 2);
+   szBuff[2] = '\0';
+   tm->tm_mday = atol(szBuff);
+   if ((tm->tm_mday > 31) || (tm->tm_mday < 1))
+      tm->tm_mday = 31;
+
+   /* hour, minute, second */
+   memcpy(szBuff, &(szText[9]), 2);
+   szBuff[2] = '\0';
+   tm->tm_hour = atol(szBuff);
+   if ((tm->tm_hour > 23) || (tm->tm_hour < 0))
+      tm->tm_hour = 23;
+
+   memcpy(szBuff, &(szText[11]), 2);
+   szBuff[2] = '\0';
+   tm->tm_min = atol(szBuff);
+   if ((tm->tm_min > 59) || (tm->tm_min < 0))
+      tm->tm_min = 59;
+
+   memcpy(szBuff, &(szText[13]), 2);
+   szBuff[2] = '\0';
+   tm->tm_sec = atol(szBuff);
+   if ((tm->tm_sec > 59) || (tm->tm_sec < 0))
+      tm->tm_sec = 59;
+
+   return true;
+}
+
+int msgsvc_check_utf8(char c)
+{
+       if ((c & 0xff) < (128 & 0xff))
+               return 1;
+       else if ((c & (char)0xe0) == (char)0xc0)
+               return 2;
+       else if ((c & (char)0xf0) == (char)0xe0)
+               return 3;
+       else if ((c & (char)0xf8) == (char)0xf0)
+               return 4;
+       else if ((c & (char)0xfc) == (char)0xf8)
+               return 5;
+       else if ((c & (char)0xfe) == (char)0xfc)
+               return 6;
+       else
+               return MSG_ERR_INVALID_PARAMETER;
+}
+
+char* __msgsvc_vmsg_convert_tm_to_vdata_str(struct tm * tm)
+{
+       char str[22] = {0, };
+       char APM[3] = {0, };
+       char month[15] = {0, };
+       int mon = 0;
+       int hour = 0;
+       mon = tm->tm_mon + 1;
+       int wrn=0;
+
+       if (tm->tm_hour >= 12)
+               strncpy(APM, "PM", 3);
+       else
+               strncpy(APM, "AM", 3);
+
+       if (tm->tm_hour > 12)
+               hour = tm->tm_hour - 12;
+       else
+               hour = tm->tm_hour;
+
+       switch(mon) {
+               case 1:
+                       strncpy(month, "Jan", 4);
+                       break;
+               case 2:
+                       strncpy(month, "Feb", 4);
+                       break;
+               case 3:
+                       strncpy(month, "Mar", 4);
+                       break;
+               case 4:
+                       strncpy(month, "Apr", 4);
+                       break;
+               case 5:
+                       strncpy(month, "May", 4);
+                       break;
+               case 6:
+                       strncpy(month, "Jun", 4);
+                       break;
+               case 7:
+                       strncpy(month, "Jul", 4);
+                       break;
+               case 8:
+                       strncpy(month, "Aug", 4);
+                       break;
+               case 9:
+                       strncpy(month, "Sep", 4);
+                       break;
+               case 10:
+                       strncpy(month, "Oct", 4);
+                       break;
+               case 11:
+                       strncpy(month, "Nov", 4);
+                       break;
+               case 12:
+                       strncpy(month, "Dec", 4);
+                       break;
+               default:
+                       MSG_DEBUG("invalid month number");
+               break;
+       }
+
+       wrn = snprintf(str, 22, "%d:%02d%s, %04d %s %d",
+               hour,
+               tm->tm_min,
+               APM,
+               tm->tm_year + 1900,
+               month,
+               tm->tm_mday);
+       if(wrn < 0)
+               MSG_DEBUG("snprintf was failed  ");
+
+       return strdup(str);
+}
+static inline int __msgsvc_vmsg_add_folding(char **buf, int *buf_size, int buf_len)
+{
+       int char_len = 0;
+       char *buf_copy = NULL;
+       int len, result_len;
+       char *r;
+       const char *s;
+       bool content_start = false;
+       bool encode_64 = false;
+
+       buf_copy = (char *)calloc(1, *buf_size);
+
+       if (buf_copy == NULL)
+               return -1;
+
+       s = *buf;
+       r = buf_copy;
+       len = result_len = 0;
+
+       while (*s) {
+               if (*buf_size < result_len + 5) {
+                       char *tmp = NULL;
+                       *buf_size = *buf_size + 1000;
+                       if (NULL == (tmp = (char *)realloc(buf_copy, *buf_size))) {
+                               free(buf_copy);
+                               return -1;
+                       } else {
+                               buf_copy = tmp;
+                               r = (buf_copy + result_len);
+                       }
+               }
+
+               if (false == content_start) {
+                       if (':' == *s)
+                               content_start = true;
+                       else if (0 == strncmp(s, "ENCODING=BASE64", strlen("ENCODING=BASE64")))
+                               encode_64 = true;
+               }
+
+               if ('\r' == *s) {
+                       len--;
+               } else if ('\n' == *s) {
+                       len = -1;
+                       char_len = 0;
+                       content_start = false;
+                       encode_64 = false;
+               }
+
+               if (0 == char_len) {
+                       if (false == encode_64)
+                               char_len = msgsvc_check_utf8(*s);
+
+                       if (MSGSVC_VMSG_FOLDING_LIMIT <= len + char_len) {
+                               *r = '\r';
+                               r++;
+                               *r = '\n';
+                               r++;
+                               *r = ' ';
+                               r++;
+                               len = 1;
+                               result_len += 3;
+                       }
+               }
+
+               if (char_len)
+                       char_len--;
+
+               *r = *s;
+               r++;
+               s++;
+               len++;
+               result_len++;
+       }
+       *r = '\0';
+       free(*buf);
+       *buf = buf_copy;
+       return result_len;
+}
+
+static inline int __msgsvc_vmsg_append_start_vmsg_1_1(char **buf, int *buf_size, int len)
+{
+       MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[BEGIN_VMSG]);
+       MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
+       MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[VERSION_VMSG]);
+       MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
+       return len;
+}
+
+static inline int __msgsvc_vmsg_append_end_vmsg(char **buf, int *buf_size, int len)
+{
+       MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[END_VMSG]);
+       MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
+       return len;
+}
+
+static inline int __msgsvc_vmsg_append_read_status(MSG_MESSAGE_INFO_S *pMsg, char **buf, int *buf_size, int len)
+{
+       MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[VMSG_INDICATION_READ_STATUS]);
+       MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[VMSG_DATA_SEPARATOR]);
+       if (pMsg->bRead) {
+               MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[VMSG_INDICATION_READ_STATUS_READ]);
+               MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
+       } else {
+               MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[VMSG_INDICATION_READ_STATUS_UNREAD]);
+               MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
+       }
+       return len;
+}
+static inline int __msgsvc_vmsg_append_box_type(MSG_MESSAGE_INFO_S *pMsg, char **buf, int *buf_size, int len)
+{
+       MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[VMSG_INDICATION_MSG_BOX]);
+       MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[VMSG_DATA_SEPARATOR]);
+       switch(pMsg->folderId) {
+               case MSG_INBOX_ID:
+                       MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[VMSG_INDICATION_MSG_BOX_INBOX]);
+
+                       break;
+               case MSG_SENTBOX_ID:
+                       MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[VMSG_INDICATION_MSG_BOX_SENT]);
+
+                       break;
+               case MSG_DRAFT_ID:
+                       MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[VMSG_INDICATION_MSG_BOX_DRAFT]);
+                       break;
+               default:
+                       /* Discard User Defined, outbox or Spam folder's messages. */
+                       MSG_DEBUG("Invalid or unhandled msg box");
+       }
+       MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
+       return len;
+}
+
+static inline int __msgsvc_vmsg_append_msg_type(MSG_MESSAGE_INFO_S *pMsg, char **buf, int *buf_size, int len)
+{
+       /* TO DO check with msg text contains Only PrintableAscii if true then else handle INET_TYPE */
+       MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[VMSG_INDICATION_MESSAGE_TYPE]);
+       MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[VMSG_DATA_SEPARATOR]);
+       MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[VMSG_INDICATION_MESSAGE_TYPE_MSG]);
+       MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
+       return len;
+}
+
+static inline int __msgsvc_vmsg_append_origin_address_vcard(MSG_MESSAGE_INFO_S *pMsg, char **buf, int *buf_size, int len)
+{
+       MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[BEGIN_VCARD]);
+       MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
+       MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[VERSION_VCARD]);
+       MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
+       char originAddress[MAX_ADDRESS_VAL_LEN + 1] = {0, };
+       bool isDisplayName = false;
+
+       signed char folderId = (signed char)pMsg->folderId;
+       if (folderId == (signed char)MSG_INBOX_ID) {
+               snprintf(originAddress, sizeof(originAddress), "%s", pMsg->addressList[0].addressVal);
+       }
+
+       needCharset = true; /* as per android */
+
+       if (strlen(originAddress) > 0) {
+               MSG_CONTACT_INFO_S contactInfo;
+               memset(&contactInfo, 0x00, sizeof(MSG_CONTACT_INFO_S));
+
+               if (MsgGetContactInfo(&(pMsg->addressList[0]), &contactInfo) != MSG_SUCCESS) {
+                       MSG_WARN("MsgGetContactInfo() fail.");
+               }
+               snprintf(pMsg->addressList[0].displayName, sizeof(pMsg->addressList[0].displayName), "%s", contactInfo.firstName);
+               if (pMsg->addressList[0].displayName[0] != '\0')
+                       isDisplayName = true;
+               if (needCharset && isDisplayName) {
+                       MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[FNAME_UTF8_VCARD]);
+                       MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, pMsg->addressList->displayName);
+                       MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
+                       MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[NAME_UTF8_VCARD]);
+                       MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, pMsg->addressList->displayName);
+                       MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
+               } else {
+                       MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[FNAME_VCARD]);
+                       MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, pMsg->addressList->displayName);
+                       MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
+                       MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[NAME_VCARD]);
+                       MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, pMsg->addressList->displayName);
+                       MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
+               }
+               if (MsgIsNumber(originAddress)) {
+                       MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[TEL_VCARD]);
+                       MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[TEL_VCARD_CELL]);
+                       MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, originAddress);
+                       MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
+               }
+       } else {
+               MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[FNAME_VCARD]);
+               MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
+               MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[NAME_VCARD]);
+               MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
+       }
+
+
+       MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[END_VCARD]);
+       MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
+       return len;
+}
+
+static inline int __msgsvc_vmsg_append_recipient_address_vcard(MSG_MESSAGE_INFO_S *pMsg, char **buf, int *buf_size, int len)
+{
+       MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[BEGIN_VCARD]);
+       MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
+       MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[VERSION_VCARD]);
+       MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
+
+       needCharset = true; /* as per android */
+       signed char folderId;
+
+       for (int i = 0; i < pMsg->nAddressCnt; ++i) {
+               char originAddress[MAX_ADDRESS_VAL_LEN + 1] = {0, };
+               bool isDisplayName = false;
+
+               folderId = (signed char)pMsg->folderId;
+               if (folderId == MSG_SENTBOX_ID) {
+                       snprintf(originAddress, sizeof(originAddress), "%s", pMsg->addressList[0].addressVal);
+               }
+
+               if (strlen(originAddress) > 0) {
+                       MSG_CONTACT_INFO_S contactInfo;
+                       memset(&contactInfo, 0x00, sizeof(MSG_CONTACT_INFO_S));
+
+                       if (MsgGetContactInfo(&(pMsg->addressList[i]), &contactInfo) != MSG_SUCCESS) {
+                               MSG_WARN("MsgGetContactInfo() fail.");
+                       }
+                       snprintf(pMsg->addressList[i].displayName, sizeof(pMsg->addressList[i].displayName), "%s", contactInfo.firstName);
+                       if (pMsg->addressList[i].displayName[0] != '\0')
+                               isDisplayName = true;
+                       if (needCharset && isDisplayName) {
+                               MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[FNAME_UTF8_VCARD]);
+                               MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, pMsg->addressList[i].displayName);
+                               MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
+                               MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[NAME_UTF8_VCARD]);
+                               MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, pMsg->addressList[i].displayName);
+                               MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
+                       } else {
+                               MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[FNAME_VCARD]);
+                               MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, pMsg->addressList[i].displayName);
+                               MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
+                               MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[NAME_VCARD]);
+                               MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, pMsg->addressList[i].displayName);
+                               MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
+                       }
+                       if (MsgIsNumber(originAddress)) {
+                               MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[TEL_VCARD]);
+                               MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[TEL_VCARD_CELL]);
+                               MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, originAddress);
+                               MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
+                       }
+               } else {
+                       MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[FNAME_VCARD]);
+                       MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
+                       MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[NAME_VCARD]);
+                       MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
+               }
+       }
+
+       MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[END_VCARD]);
+       MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
+
+       return len;
+}
+
+static inline int __msgsvc_vmsg_append_msg_body(MSG_MESSAGE_INFO_S *pMsg, char **buf, int *buf_size, int len)
+{
+       struct tm       display_time;
+
+       MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[BEGIN_VENV]);
+       MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
+
+       MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[BEGIN_VBODY]);
+       MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
+
+       /* Date: */
+       MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[VMSG_BODY_PROPERTY_DATE]);
+       MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[VMSG_DATA_SEPARATOR]);
+       tzset();
+       localtime_r(&(pMsg->displayTime), &display_time);
+       char *msgDate = __msgsvc_vmsg_convert_tm_to_vdata_str(&display_time);
+       if (msgDate !=NULL) {
+               MSGSVC_VMSG_APPEND_STR_FREE(buf, buf_size, len, msgDate);
+               g_free(msgDate);
+               MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
+       }
+
+       /* Subject: */
+       if (pMsg->subject[0] != '\0') {
+               MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[VMSG_BODY_PROPERTY_SUBJECT]);
+               MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[VMSG_DATA_SEPARATOR]);
+               MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, pMsg->subject);
+               MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
+       }
+
+       /* body: */
+       if(pMsg->msgType.mainType == MSG_SMS_TYPE) {
+               if(pMsg->msgType.subType == MSG_NORMAL_SMS) {
+                       if (pMsg->bTextSms == false) {
+                               char* pFileData = NULL;
+                               unique_ptr<char*, void(*)(char**)> buff(&pFileData, unique_ptr_deleter);
+
+                               int             fileSize = 0;
+                               char*   msgText = NULL;
+
+                               if (MsgOpenAndReadFile(pMsg->msgData, &pFileData, &fileSize) == false)
+                                       return len;
+
+                               msgText = (char *)calloc(1, fileSize);
+                               memcpy(msgText, pFileData, fileSize);
+                               MSGSVC_VMSG_APPEND_STR_FREE(buf, buf_size, len, msgText);
+                               g_free(msgText);
+                       } else {
+                               MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, pMsg->msgText);
+                       }
+               }
+       }
+
+       MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
+
+       MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[END_VBODY]);
+       MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
+
+       MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[END_VENV]);
+       MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
+       return len;
+}
+
+static inline int __msgsvc_vmsg_append_msg_envelope(MSG_MESSAGE_INFO_S *pMsg, char **buf, int *buf_size, int len)
+{
+       MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[BEGIN_VENV]);
+       MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
+
+       len = __msgsvc_vmsg_append_recipient_address_vcard(pMsg, buf, buf_size, len);
+       MSG_ERR_RET_VM(len < 0, len, "Invalid length : vcard");
+
+       len = __msgsvc_vmsg_append_msg_body(pMsg, buf, buf_size, len);
+       MSG_ERR_RET_VM(len < 0, len, "Invalid length : body");
+
+       MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[END_VENV]);
+       MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
+       return len;
+}
+
+static inline int __msgsvc_vmsg_append_msg(MSG_MESSAGE_INFO_S *pMsg, char **buf, int *buf_size, int len)
+{
+       len = __msgsvc_vmsg_append_read_status(pMsg, buf, buf_size, len);
+       MSG_ERR_RET_VM(len < 0, len, "Invalid length : read status");
+
+       len = __msgsvc_vmsg_append_box_type(pMsg, buf, buf_size, len);
+       MSG_ERR_RET_VM(len < 0, len, "Invalid length : box type");
+
+       len = __msgsvc_vmsg_append_msg_type(pMsg, buf, buf_size, len);
+       MSG_ERR_RET_VM(len < 0, len, "Invalid length : msg type");
+
+       len = __msgsvc_vmsg_append_origin_address_vcard(pMsg, buf, buf_size, len);
+       MSG_ERR_RET_VM(len < 0, len, "Invalid length : origin address");
+
+       len = __msgsvc_vmsg_append_msg_envelope(pMsg, buf, buf_size, len);
+       MSG_ERR_RET_VM(len < 0, len, "Invalid length : envelop");
+
+       return len;
+}
+
+char *MsgVMessageEncode(MSG_MESSAGE_INFO_S *pMsg)
 {
        MSG_BEGIN();
 
@@ -103,12 +989,18 @@ char* MsgVMessageAddRecord(MsgDbHandler *pDbHandle, MSG_MESSAGE_INFO_S* pMsg)
        VParam*         param = NULL;
        VTree *         pBody = NULL;
        VTree *         pCard = NULL;
-       VTree *         pCurrent= NULL;
+       VTree *         pCurrent = NULL;
        struct tm       display_time;
        char*           encoded_data = NULL;
-       int                     err = MSG_SUCCESS;
 
        VTree* pMessage = NULL;
+
+       /* to encode sms */
+       if (pMsg->msgType.mainType == MSG_SMS_TYPE && pMsg->msgType.subType == MSG_NORMAL_SMS) {
+               return MsgVMessageEncodeSMS(pMsg);
+       }
+
+       /* to encode mms */
        if (pMessage == NULL) {
                pMessage = (VTree *)malloc(sizeof(VTree));
                if (!pMessage) {
@@ -118,26 +1010,22 @@ char* MsgVMessageAddRecord(MsgDbHandler *pDbHandle, MSG_MESSAGE_INFO_S* pMsg)
                pMessage->pTop = NULL;
                pMessage->pCur = NULL;
                pMessage->pNext = NULL;
-
        }
                pCurrent = pMessage;
 
-       //Insert VObject (X-MESSAGE-TYPE) to VMessage tree
+       /* Insert VObject (X-MESSAGE-TYPE) to VMessage tree */
        INSERT_VMSG_OBJ;
 
        pObject->property = VMSG_TYPE_MSGTYPE;
 
-       if(pMsg->msgType.subType == MSG_NORMAL_SMS)
-               pObject->pszValue[0] = strdup("SMS");
+       if (pMsg->msgType.mainType == MSG_MMS_TYPE && (pMsg->msgType.subType == MSG_SENDREQ_MMS || pMsg->msgType.subType == MSG_SENDCONF_MMS))
+               pObject->pszValue[0] = strdup("MMS SEND");
 #if 0
-       else if(pMsg->msgType.mainType == MSG_MMS_TYPE && pMsg->msgType.subType == MSG_NOTIFICATIONIND_MMS)
+       else if (pMsg->msgType.mainType == MSG_MMS_TYPE && pMsg->msgType.subType == MSG_NOTIFICATIONIND_MMS)
                pObject->pszValue[0] = strdup("MMS NOTIFICATION");
 #endif
 
-       else if(pMsg->msgType.mainType == MSG_MMS_TYPE && (pMsg->msgType.subType == MSG_SENDREQ_MMS || pMsg->msgType.subType == MSG_SENDCONF_MMS))
-               pObject->pszValue[0] = strdup("MMS SEND");
-
-       else if(pMsg->msgType.mainType == MSG_MMS_TYPE && (pMsg->msgType.subType == MSG_RETRIEVE_AUTOCONF_MMS || pMsg->msgType.subType == MSG_RETRIEVE_MANUALCONF_MMS))
+       else if (pMsg->msgType.mainType == MSG_MMS_TYPE && (pMsg->msgType.subType == MSG_RETRIEVE_AUTOCONF_MMS || pMsg->msgType.subType == MSG_RETRIEVE_MANUALCONF_MMS))
                pObject->pszValue[0] = strdup("MMS RETRIEVED");
 
        else
@@ -146,13 +1034,12 @@ char* MsgVMessageAddRecord(MsgDbHandler *pDbHandle, MSG_MESSAGE_INFO_S* pMsg)
        pObject->valueCount = 1;
 
 
-       //Insert VObject (X-IRMC-BOX) to VMessate tree
+       /* Insert VObject (X-IRMC-BOX) to VMessate tree */
        INSERT_VMSG_OBJ;
 
        pObject->property = VMSG_TYPE_MSGBOX;
 
-       switch(pMsg->folderId)
-       {
+       switch(pMsg->folderId) {
                case MSG_INBOX_ID:
                        pObject->pszValue[0] = strdup("INBOX");
                        break;
@@ -166,27 +1053,28 @@ char* MsgVMessageAddRecord(MsgDbHandler *pDbHandle, MSG_MESSAGE_INFO_S* pMsg)
                        pObject->pszValue[0] = strdup("DRAFTBOX");
                        break;
                default:
-                       // Discard User Defined or Spam folder's messages.
+                       /* Discard User Defined or Spam folder's messages. */
                        goto __CATCH_FAIL__;
        }
        pObject->valueCount = 1;
 
 
-       //Insert VObject (X-SS-DT) to VMessage tree
+       /* Insert VObject (X-SS-DT) to VMessage tree */
        INSERT_VMSG_OBJ;
 
        pObject->property = VMSG_TYPE_DATE;
+       tzset();
        localtime_r(&(pMsg->displayTime), &display_time);
        pObject->pszValue[0] = _convert_tm_to_vdata_str(&display_time);
        pObject->valueCount = 1;
 
 
-       //Insert Vobject read status to VMessage tree
+       /* Insert Vobject read status to VMessage tree */
        INSERT_VMSG_OBJ;
 
        pObject->property = VMSG_TYPE_STATUS;
 
-       if(pMsg->bRead)
+       if (pMsg->bRead)
                pObject->pszValue[0] = strdup("READ");
        else
                pObject->pszValue[0] = strdup("UNREAD");
@@ -194,7 +1082,7 @@ char* MsgVMessageAddRecord(MsgDbHandler *pDbHandle, MSG_MESSAGE_INFO_S* pMsg)
        pObject->valueCount = 1;
 
 
-       //Insert VBody  tree for message body;
+       /* Insert VBody  tree for message body; */
        pBody = (VTree*)calloc(1, sizeof(VTree));
        if ( !pBody )
                goto __CATCH_FAIL__;
@@ -205,63 +1093,29 @@ char* MsgVMessageAddRecord(MsgDbHandler *pDbHandle, MSG_MESSAGE_INFO_S* pMsg)
        pCurrent->pNext = pBody;
        pCurrent = pBody;
 
-if(strlen(pMsg->subject) > 0)
-{
-       //Insert Subject object
-       INSERT_VBODY_OBJ;
-       pObject->property = VMSG_TYPE_SUBJECT;
-       pObject->pszValue[0] = strdup(pMsg->subject);
-       pObject->valueCount = 1;
-}
-       //Insert VBody object
+       if (strlen(pMsg->subject) > 0) {
+               /* Insert Subject object */
+               INSERT_VBODY_OBJ;
+               pObject->property = VMSG_TYPE_SUBJECT;
+               pObject->pszValue[0] = strdup(pMsg->subject);
+               pObject->valueCount = 1;
+       }
+       /* Insert VBody object */
        INSERT_VBODY_OBJ;
        pObject->property = VMSG_TYPE_BODY;
 
-       if(pMsg->msgType.mainType == MSG_SMS_TYPE)
-       {
-               if(pMsg->msgType.subType == MSG_NORMAL_SMS)
-               {
-                       if (pMsg->bTextSms == false)
-                       {
-                               char* pFileData = NULL;
-                               AutoPtr<char> buf(&pFileData);
-
-                               int             fileSize = 0;
-                               char*   msgText = NULL;
-
-                               if (MsgOpenAndReadFile(pMsg->msgData, &pFileData, &fileSize) == false)
-                                       goto __CATCH_FAIL__;
-
-                               msgText = (char *)calloc(1, fileSize);
-                               memcpy(msgText, pFileData, fileSize);
-                               pObject->numOfBiData = fileSize;
-                               pObject->pszValue[0] = msgText;
-                       }
-                       else
-                       {
-                               pObject->numOfBiData = pMsg->dataSize;
-                               pObject->pszValue[0] = strdup(pMsg->msgText);
-                       }
-                       pObject->valueCount = 1;
-               }
-               else
-                       goto __CATCH_FAIL__;
-       }
-
-       else if(pMsg->msgType.mainType == MSG_MMS_TYPE)
-       {
-               //Insert VBody for mms raw data;
+       if (pMsg->msgType.mainType == MSG_MMS_TYPE) {
+               /* Insert VBody for mms raw data; */
                char* pFileData = NULL;
-
-               int             fileSize = 0;
-               char*   msgText = NULL;
-               char            filePath[MSG_FILEPATH_LEN_MAX] = {0, };
-
-               if(pMsg->msgType.subType == MSG_NOTIFICATIONIND_MMS)
+               unique_ptr<char*, void(*)(char**)> buf(&pFileData, unique_ptr_deleter);
+               MMS_DATA_S *pMmsData = NULL;
+               int fileSize = 0;
+               char* msgText = NULL;
+#if 0
+               char filePath[MSG_FILEPATH_LEN_MAX] = {0, };
+               if(pMsg->msgType.subType == MSG_NOTIFICATIONIND_MMS) {
                        pFileData = MsgOpenAndReadMmsFile(pMsg->msgData, 0, -1, &fileSize);
-
-               else
-               {
+               } else {
                        err = MsgStoGetMmsRawFilePath(pDbHandle, pMsg->msgId, filePath);
 
                        if (err != MSG_SUCCESS)
@@ -269,30 +1123,66 @@ if(strlen(pMsg->subject) > 0)
 
                        pFileData = MsgOpenAndReadMmsFile(filePath, 0, -1, &fileSize);
                }
-               MSG_DEBUG("FILE SIZE IS %d", fileSize);
-               msgText = (char *)calloc(1, fileSize);
-               if(pFileData)
-                       memcpy(msgText, pFileData, fileSize);
-               pObject->numOfBiData = fileSize;
-               pObject->pszValue[0] = msgText;
-               pObject->valueCount = 1;
+#else
+
+               if (pMsg->bTextSms == false) {
+                       if (MsgOpenAndReadFile(pMsg->msgData, &pFileData, &fileSize) == false) {
+                               goto __CATCH_FAIL__;
+                       }
+               } else {
+                       fileSize = strlen(pMsg->msgData);
+                       pFileData = new char[fileSize+1];
+                       if (!pFileData)
+                               goto __CATCH_FAIL__;
+                       memset(pFileData, 0x00, fileSize+1);
+                       snprintf(pFileData, fileSize, "%s", pMsg->msgData);
+               }
+
+               if (MsgDeserializeMmsData(pFileData, fileSize, &pMmsData) != 0) {
+                       MSG_DEBUG("Fail to Deserialize Message Data");
+                       MsgMmsRelease(&pMmsData);
+                       goto __CATCH_FAIL__;
+               }
+
+               int serializedDataSize = 0;
+
+               if (pMmsData) {
+                       MsgMmsSetMultipartListData(pMmsData); /* app file -> data */
+                       serializedDataSize = MsgSerializeMms(pMmsData, &pFileData);
+               }
 
                if (pFileData) {
-                       free(pFileData);
+                       fileSize = serializedDataSize;
+               }
+
+               MsgMmsRelease(&pMmsData);
+
+#endif
+               MSG_DEBUG("FILE SIZE IS %d, %s", fileSize, pFileData);
+               if (fileSize > 0) {
+                       msgText = (char *)calloc(1, fileSize);
+                       if(pFileData && msgText)
+                               memcpy(msgText, pFileData, fileSize);
+               }
+               pObject->numOfBiData = fileSize;
+               pObject->pszValue[0] = msgText;
+               pObject->valueCount = 1;
+
+               if (pFileData) {
+                       delete [] pFileData;
                        pFileData = NULL;
                }
        }
 
-       // Insert parameter for base64 encoding
+       /* Insert parameter for base64 encoding */
        MSG_DEBUG("before to start INSERT_PARAM");
        INSERT_PARAM;
        pObject->pParam = param;
        param->parameter = VMSG_PARAM_ENCODING;
        param->paramValue = VMSG_ENC_PARAM_BASE64;
 
-       // Add VCard tree for recipient address information.
-       for(int i = 0; i < pMsg->nAddressCnt; ++i)
-       {
+       /* Add VCard tree for recipient address information. */
+       for (int i = 0; i < pMsg->nAddressCnt; ++i) {
                pCard = (VTree*)calloc(1, sizeof(VTree));
                if ( !pCard )
                        goto __CATCH_FAIL__;
@@ -306,7 +1196,7 @@ if(strlen(pMsg->subject) > 0)
 
                INSERT_VCARD_OBJ;
                pObject->property = VCARD_TYPE_TEL;
-               pObject->pszValue       [0] = strdup(pMsg->addressList[i].addressVal);
+               pObject->pszValue[0] = strdup(pMsg->addressList[i].addressVal);
                pObject->valueCount = 1;
        }
        MSG_DEBUG("before to start vmsg_encode");
@@ -317,304 +1207,908 @@ if(strlen(pMsg->subject) > 0)
        return encoded_data;
 
 __CATCH_FAIL__ :
-       vmsg_free_vtree_memory( pMessage );
+       vmsg_free_vtree_memory(pMessage);
 
        return NULL;
 }
 
+char *MsgVMessageEncodeSMS(MSG_MESSAGE_INFO_S *pMsg)
+{
+       MSG_BEGIN();
 
-char* _convert_tm_to_vdata_str(const struct tm * tm)
+       char *buf = NULL;
+       int buf_size = VMSG_INIT_LENGTH;
+       int len = 0;
+
+       __msgsvc_vmsg_initial();
+
+       buf = (char *)calloc(1, buf_size);
+
+       len = __msgsvc_vmsg_append_start_vmsg_1_1(&buf, &buf_size, len);
+       if (len < 0) {
+               free(buf);
+               return NULL;
+       }
+
+       len = __msgsvc_vmsg_append_msg(pMsg, &buf, &buf_size, len);
+       if (len < 0) {
+               free(buf);
+               return NULL;
+       }
+
+       len = __msgsvc_vmsg_append_end_vmsg(&buf, &buf_size, len);
+       if (len < 0) {
+               free(buf);
+               return NULL;
+       }
+
+       len = __msgsvc_vmsg_add_folding(&buf, &buf_size, len);
+       if (len < 0) {
+               free(buf);
+               return NULL;
+       }
+
+       MSG_END();
+       return buf;
+}
+bool __msgsvc_vmsg_convert_vdata_to_tm_str(const char* szText, struct tm * tm)
 {
-       char str[17] = {0, };
+       if (szText == NULL)
+               return false;
+
+       char delims[] = ",";
+       gchar **token = NULL;
+       struct tm tmTemp;
+
+       token = g_strsplit_set(szText, delims, -1);
+       if (token && token[0]) {
+               g_strstrip(token[0]);
+               strptime(token[0], "%I:%M%p", tm);
+       } else {
+               g_strfreev(token);
+               return false;
+       }
 
-       snprintf(str, 17, "%04d%02d%02dT%02d%02d%02dZ",
-               tm->tm_year + 1900,
-               tm->tm_mon +1,
-               tm->tm_mday,
-               tm->tm_hour,
-               tm->tm_min,
-               tm->tm_sec);
+       if (token && token[1]) {
+               g_strstrip(token[1]);
+               strptime(token[1], "%Y %b %e", &tmTemp);
+       } else {
+               g_strfreev(token);
+               return false;
+       }
 
-       return strdup(str);
+       tm->tm_year = tmTemp.tm_year;
+       tm->tm_mon = tmTemp.tm_mon;
+       tm->tm_mday = tmTemp.tm_mday;
+       tm->tm_sec = 0;
+
+       g_strfreev(token);
+       return true;
 }
 
 
-bool _convert_vdata_str_to_tm(const char* szText, struct tm * tm)
+static inline char* __msgsvc_vmsg_remove_empty_line(char *src)
 {
+       while (*src) {
+               if ('\n' != *src && '\r' != *src)
+                       break;
+               src++;
+       }
+       return src;
+}
 
-   if (szText == NULL) return false;
-   if (strlen(szText) < 15) return false;
-   if (szText[8] != 'T') return false;
+static char* __msgsvc_vmsg_check_word(char *src, const char *word)
+{
+       bool start = false;
 
-   char szBuff[8]={0};
-   memset(tm, 0, sizeof(struct tm));
+       MSG_ERR_RET_VM(NULL == src, NULL, "The src is NULL.");
 
-   // year, month, day
-   memcpy(szBuff, &(szText[0]), 4);
-   szBuff[4] = '\0';
-   tm->tm_year = atol(szBuff) - 1900;
-   if ((tm->tm_year > 137) || (tm->tm_year < 0))
-      tm->tm_year = 0;
+       src = __msgsvc_vmsg_remove_empty_line(src);
 
-   memcpy(szBuff, &(szText[4]), 2);
-   szBuff[2] = '\0';
-   tm->tm_mon = atol(szBuff)-1;
-   if ((tm->tm_mon > 11) || (tm->tm_mon < 0))
-      tm->tm_mon = 11;
-
-   memcpy(szBuff, &(szText[6]), 2);
-   szBuff[2] = '\0';
-   tm->tm_mday = atol(szBuff);
-   if ((tm->tm_mday > 31) || (tm->tm_mday < 1))
-      tm->tm_mday = 31;
+       while (*src) {
+               switch (*src) {
+               case ' ':
+               case ':':
+               case ';':
+                       src++;
+                       break;
+               default:
+                       start = true;
+                       break;
+               }
+               if (start) break;
+       }
 
-   // hour, minute, second
-   memcpy(szBuff, &(szText[9]), 2);
-   szBuff[2] = '\0';
-   tm->tm_hour = atol(szBuff);
-   if ((tm->tm_hour > 23) || (tm->tm_hour < 0))
-      tm->tm_hour = 23;
+       while (*src == *word) {
+               src++;
+               word++;
 
-   memcpy(szBuff, &(szText[11]), 2);
-   szBuff[2] = '\0';
-   tm->tm_min = atol(szBuff);
-   if ((tm->tm_min > 59) || (tm->tm_min < 0))
-      tm->tm_min = 59;
+               if ('\0' == *src || '\0' == *word)
+                       break;
+       }
 
-   memcpy(szBuff, &(szText[13]), 2);
-   szBuff[2] = '\0';
-   tm->tm_sec = atol(szBuff);
-   if ((tm->tm_sec > 59) || (tm->tm_sec < 0))
-      tm->tm_sec = 59;
+       if ('\0' == *word)
+               return src;
+       else
+               return NULL;
+}
 
-   return true;
+static inline int __msgsvc_vmsg_check_quoted(char *src, int max, int *quoted)
+{
+       int ret;
+       if (TRUE == *quoted)
+               return TRUE;
+
+       while (*src && max) {
+               if ('Q' == *src) {
+                       ret = strncmp(src, "QUOTED-PRINTABLE", sizeof("QUOTED-PRINTABLE") - 1);
+                       if (!ret) {
+                               *quoted = TRUE;
+                               return TRUE;
+                       }
+               } else if (':' == *src) {
+                       break;
+               }
+               src++;
+               max--;
+       }
+       return FALSE;
 }
 
-char *MsgVMessageEncode(MSG_MESSAGE_INFO_S *pMsg)
+static inline int __msgsvc_vmsg_remove_folding(char *folded_src)
 {
-       MSG_BEGIN();
+       char *result = folded_src;
 
-       MsgDbHandler dbHandle;
-       VObject *pObject = NULL;
-       VParam *param = NULL;
-       VTree *pBody = NULL;
-       VTree *pCard = NULL;
-       VTree *pCurrent= NULL;
-       VTree *pMessage = NULL;
+       MSG_ERR_RET_VM(NULL == folded_src, MSG_ERR_INVALID_PARAMETER, " Invalid Parameter : __msgsvc_vmsg_remove_folding");
 
-       struct tm       display_time;
-       char *encoded_data = NULL;
-       int err = MSG_SUCCESS;
+       while (*folded_src) {
+               if ('\r' == *folded_src && '\n' == *(folded_src+1) && ' ' == *(folded_src+2))
+                       folded_src += 3;
+               else if ('\n' == *folded_src && ' ' == *(folded_src+1))
+                       folded_src += 2;
 
-       if (pMessage == NULL) {
-               pMessage = (VTree *)malloc(sizeof(VTree));
-               if (!pMessage) {
+               if ('\0' == *folded_src)
+                       break;
+
+               *result = *folded_src;
+               result++;
+               folded_src++;
+       }
+       *result = '\0';
+       return MSG_SUCCESS;
+}
+
+static inline int __msgsvc_vmsg_hex_to_dec(char hex)
+{
+       switch (hex) {
+       case '0' ... '9':
+               return hex - '0';
+       case 'a' ... 'f':
+               return hex - 'a' + 10;
+       case 'A' ... 'F':
+               return hex - 'A' + 10;
+       default:
+               return -1;
+       }
+}
+static inline int __msgsvc_vmsg_decode_quoted_val(char *val)
+{
+       char *src, *dest;
+       int pre;
+
+       src = strchr(val, ':');
+       if (NULL == src)
+               src = val;
+
+       dest = src;
+       while (*src) {
+               if ('=' == *src) {
+                       pre = __msgsvc_vmsg_hex_to_dec(*(src+1));
+                       if (0 <= pre) {
+                               *dest = (char)((pre << 4) + __msgsvc_vmsg_hex_to_dec(*(src+2)));
+                               dest++;
+                               src += 2;
+                       } else {
+                               if ('\r' == *(src+1) && '\n' == *(src+2))
+                                       src += 2;
+                       }
+               } else {
+                       *dest = *src;
+                       dest++;
+               }
+               src++;
+       }
+
+       *dest = '\0';
+       return dest - val;
+}
+
+static inline char* __msgsvc_vmsg_translate_charset(char *src, int len)
+{
+       int ret;
+       char *val = src;
+
+       while (*val) {
+               if ('C' == *val) {
+                       ret = strncmp(val, "CHARSET", sizeof("CHARSET") - 1);
+                       if (!ret) {
+                               val += sizeof("CHARSET");
+                               break;
+                       }
+               } else if (':' == *val) {
                        return NULL;
                }
-               pMessage->treeType = VMESSAGE;
-               pMessage->pTop = NULL;
-               pMessage->pCur = NULL;
-               pMessage->pNext = NULL;
+               val++;
+       }
+
+       if (*val) {
+               UChar *temp;
+               UConverter *conv;
+               UErrorCode err = U_ZERO_ERROR;
+               int dest_size = 0;
+               int temp_size = 0;
+               int src_len, i = 0;
+               char enc[32] = {0}, *dest;
+
+               while (';' != *val && ':' != *val  && ',' != *val) {
+                       enc[i++] = *val++;
+               }
+               enc[i] = '\0';
+               if (0 == strcasecmp("UTF-8", enc))
+                       return NULL;
 
+               while (':' != *val)
+                       val++;
+
+               src_len = len - (val - src);
+
+               temp_size = (src_len+1) * sizeof(UChar);
+               temp = (UChar *)malloc(temp_size);
+               conv = ucnv_open(enc, &err);
+               MSG_WARN_M(U_FAILURE(err), "ucnv_open() Failed(%d), enc=%s", err, enc);
+               ucnv_toUChars(conv, temp, temp_size, val, src_len, &err);
+               MSG_WARN_M(U_FAILURE(err), "ucnv_toUChars() Failed(%d), enc=%s", err, enc);
+               ucnv_close(conv);
+
+               dest_size = temp_size*2;
+               dest = (char *)malloc(dest_size);
+               conv = ucnv_open("UTF-8", &err);
+               MSG_WARN_M(U_FAILURE(err), "ucnv_open() Failed(%d), enc=%s", err, enc);
+               ucnv_fromUChars(conv, dest, dest_size, temp, u_strlen(temp), &err);
+               MSG_WARN_M(U_FAILURE(err), "ucnv_fromUChars() Failed(%d), enc=%s", err, enc);
+               ucnv_close(conv);
+               free(temp);
+
+               return dest;
        }
-               pCurrent = pMessage;
+       return NULL;
+}
 
-       //Insert VObject (X-MESSAGE-TYPE) to VMessage tree
-       INSERT_VMSG_OBJ;
+static void __msgsvc_vmsg_get_prefix(char **prefix, char *src)
+{
+       char *temp = strchr(src, ':');
+       if (temp) {
+               long len = (long)temp - (long)src;
+               *prefix = (char *)calloc(len+1, sizeof(char));
+               if (*prefix) {
+                       snprintf(*prefix, len+1, "%s", src);
+               } else {
+                       *prefix = NULL;
+               }
+       } else {
+               *prefix = NULL;
+       }
+}
 
-       pObject->property = VMSG_TYPE_MSGTYPE;
+static void __msgsvc_vmsg_remove_spec_out(char **prefix)
+{
+       if (NULL == prefix)
+               return;
+       char *p = *prefix;
+       while (p && *p) {
+               if (*p == '(') {
+                       *p = '\0';
+                       return;
+               }
+               p++;
+       }
+}
 
-       if(pMsg->msgType.subType == MSG_NORMAL_SMS)
-               pObject->pszValue[0] = strdup("SMS");
-#if 0
-       else if(pMsg->msgType.mainType == MSG_MMS_TYPE && pMsg->msgType.subType == MSG_NOTIFICATIONIND_MMS)
-               pObject->pszValue[0] = strdup("MMS NOTIFICATION");
-#endif
+static char* __msgsvc_vmsg_get_val(int ver, char *src, char **prefix, char **dest)
+{
+       int quoted;
+       bool start = false;
+       char *cursor;
 
-       else if(pMsg->msgType.mainType == MSG_MMS_TYPE && (pMsg->msgType.subType == MSG_SENDREQ_MMS || pMsg->msgType.subType == MSG_SENDCONF_MMS))
-               pObject->pszValue[0] = strdup("MMS SEND");
+       MSG_ERR_RET_VM(NULL == src, NULL, "Invalid parameter : The src is NULL.");
+       MSG_ERR_RET_VM(NULL == dest, NULL, "sInvalid parameter : The dest is NULL.");
 
-       else if(pMsg->msgType.mainType == MSG_MMS_TYPE && (pMsg->msgType.subType == MSG_RETRIEVE_AUTOCONF_MMS || pMsg->msgType.subType == MSG_RETRIEVE_MANUALCONF_MMS))
-               pObject->pszValue[0] = strdup("MMS RETRIEVED");
+       while (*src) {
+               switch (*src) {
+               case '\n':
+                       return NULL;
+               case '\r':
+               case ' ':
+                       src++;
+                       break;
+               default:
+                       start = true;
+                       break;
+               }
+               if (start) break;
+       }
 
-       else
-               goto __CATCH_FAIL__;
+       quoted = FALSE;
+       cursor = src;
+       if (MSGSVC_VMSG_VER_1_1 == ver) {
+               while (*cursor) {
+                       if ('=' == *cursor && __msgsvc_vmsg_check_quoted(src, cursor - src, &quoted)) {
+                               if ('\r' == *(cursor+1) && '\n' == *(cursor+2))
+                                       cursor += 2;
+                       } else {
+                               if ('\r' == *cursor && '\n' == *(cursor+1) && ' ' != *(cursor+2))
+                                       break;
+                               if ('\n' == *cursor && ' ' != *(cursor+1))
+                                       break;
+                       }
 
-       pObject->valueCount = 1;
+                       cursor++;
+               }
+       } else {
+               while (*cursor) {
+                       if ('\r' == *cursor && '\n' == *(cursor+1) && ' ' != *(cursor+2))
+                               break;
 
+                       if ('\n' == *cursor && ' ' != *(cursor+1))
+                               break;
 
-       //Insert VObject (X-IRMC-BOX) to VMessate tree
-       INSERT_VMSG_OBJ;
+                       cursor++;
+               }
+       }
 
-       pObject->property = VMSG_TYPE_MSGBOX;
+       if (src == cursor) {
+               *dest = NULL;
+               return NULL;
+       } else {
+               int len = 0;
+               char temp = *cursor;
+               char *new_dest;
+
+               if (prefix)
+                       __msgsvc_vmsg_get_prefix(prefix, src);
+
+               __msgsvc_vmsg_remove_spec_out(prefix);
+
+               *cursor = '\0';
+               *dest = strdup(src);
+               if (MSGSVC_VMSG_VER_1_1 != ver)
+                       __msgsvc_vmsg_remove_folding(*dest);
+
+               if (__msgsvc_vmsg_check_quoted(*dest, -1, &quoted))
+                       len = __msgsvc_vmsg_decode_quoted_val(*dest);
+               if (0 == len)
+                       len = strlen(*dest);
+               new_dest = __msgsvc_vmsg_translate_charset(*dest, len);
+               if (new_dest) {
+                       free(*dest);
+                       *dest = new_dest;
+               }
+               *cursor = temp;
+               return (cursor + 1);
+       }
+}
 
-       switch(pMsg->folderId)
-       {
-               case MSG_INBOX_ID:
-                       pObject->pszValue[0] = strdup("INBOX");
-                       break;
-               case MSG_OUTBOX_ID:
-                       pObject->pszValue[0] = strdup("OUTBOX");
-                       break;
-               case MSG_SENTBOX_ID:
-                       pObject->pszValue[0] = strdup("SENTBOX");
+static int  __msgsvc_vmsg_check_content_type(char **vcard)
+{
+       int i;
+       char *new_start;
+       for (i = VMSG_VALUE_NONE+1; i < VMSG_MAXIMUM_VALUE; i++) {
+               new_start = __msgsvc_vmsg_check_word(*vcard, content_name[i]);
+               if (new_start && (':' == *new_start || ';' == *new_start))
                        break;
-               case MSG_DRAFT_ID:
-                       pObject->pszValue[0] = strdup("DRAFTBOX");
+       }
+
+       if (VMSG_MAXIMUM_VALUE == i) {
+               return VMSG_VALUE_NONE;
+       } else {
+               *vcard = new_start;
+               return i;
+       }
+}
+
+static inline bool __msgsvc_vmsg_check_base64_encoded(char *src)
+{
+       int ret;
+       char *tmp = src;
+
+       while (*tmp) {
+               if ('B' == *tmp) {
+                       ret = strncmp(tmp, "BASE64", sizeof("BASE64") - 1);
+                       if (!ret)
+                               return true;
+               } else if (':' == *tmp || '\r' == *tmp) {
                        break;
-               default:
-                       // Discard User Defined or Spam folder's messages.
-                       goto __CATCH_FAIL__;
+               }
+               tmp++;
        }
-       pObject->valueCount = 1;
+       return false;
+}
 
+static char* __msgsvc_vmsg_decode_base64_val(char *val)
+{
+       gsize size = 0;
+       guchar *decoded_str;
+       char *src;
+       char *dest = NULL;
+
+       src = strchr(val, ':');
+       if (NULL == src)
+               src = val;
+       else
+               src++;
 
-       //Insert VObject (X-SS-DT) to VMessage tree
-       INSERT_VMSG_OBJ;
+       decoded_str = g_base64_decode(src, &size);
 
-       pObject->property = VMSG_TYPE_DATE;
-       localtime_r(&(pMsg->displayTime), &display_time);
-       pObject->pszValue[0] = _convert_tm_to_vdata_str(&display_time);
-       pObject->valueCount = 1;
+       dest = (char *)calloc((src-val)+size+1, sizeof(char));
+       if (NULL == dest) {
+               g_free(decoded_str);
+               return NULL;
+       }
+       snprintf(dest, (src-val)+1, "%s", val);
+       snprintf(dest+(src-val), size+1, "%s", decoded_str);
+       g_free(decoded_str);
+
+       return dest;
+}
 
+static inline char*  __msgsvc_vmsg_pass_unsupported(char *vmsg)
+{
+       while (*vmsg) {
+               if ('\n' == *vmsg)
+                       return (vmsg + 1);
+               vmsg++;
+       }
 
-       //Insert Vobject read status to VMessage tree
-       INSERT_VMSG_OBJ;
+       return NULL;
+}
 
-       pObject->property = VMSG_TYPE_STATUS;
+static inline char* __msgsvc_vmsg_get_content_value(char *val)
+{
+       char *temp;
 
-       if(pMsg->bRead)
-               pObject->pszValue[0] = strdup("READ");
+       temp = strchr(val, ':');
+       if (temp)
+               temp++;
        else
-               pObject->pszValue[0] = strdup("UNREAD");
+               temp = val;
 
-       pObject->valueCount = 1;
+       MSG_ERR_RET_VM('\0' == *(temp) || '\r' == *(temp) || '\n' == *(temp),
+               NULL, "Invalid vcard content");
 
+       return temp;
+}
 
-       //Insert VBody  tree for message body;
-       pBody = (VTree*)calloc(1, sizeof(VTree));
-       if ( !pBody )
-               goto __CATCH_FAIL__;
-       pBody->treeType = VBODY;
-       pBody->pTop = NULL;
-       pBody->pCur = NULL;
-       pBody->pNext = NULL;
-       pCurrent->pNext = pBody;
-       pCurrent = pBody;
+static char* __msgsvc_vmsg_remove_escape_char(char *str)
+{
+       const char *s = SAFE_STR(str);
+       char *r = (char *)s;
+       while (*s) {
+               if (*s == '\\' && *(s+1)) {
+                       char *n = (char*)(s+1);
+                       switch ((unsigned int)*n) {
+                       case 'n':
+                       case 'N':
+                               *r = '\n';
+                               s++;
+                               break;
+                       case ';':
+                       case ':':
+                       case ',':
+                       case '<':
+                       case '>':
+                       case '\\':
+                               *r = *n;
+                               s++;
+                               break;
+                       case 0xA1: /* en/em backslash */
+                               if (*(n+1) && 0xAC == *(n+1)) {
+                                       *r = *n;
+                                       r++;
+                                       *r = *(n+1);
+                                       s+=2;
+                               }
+                               break;
+                       case 0x81:  /* en/em backslash */
+                               if (*(n+1) && 0x5F == *(n+1)) {
+                                       *r = *n;
+                                       r++;
+                                       *r = *(n+1);
+                                       s+=2;
+                               }
+                               break;
+                       default:
+                               *r = *s;
+                               break;
+                       }
+                       r++;
+                       s++;
+               } else {
+                       *r = *s;
+                       r++;
+                       s++;
+               }
+       }
+       *r = '\0';
+       return str;
+}
 
-if(strlen(pMsg->subject) > 0)
+static inline msg_error_t __msgsvc_vmsg_get_read_status(MSG_MESSAGE_INFO_S *pMsg, char *val)
 {
-       //Insert Subject object
-       INSERT_VBODY_OBJ;
-       pObject->property = VMSG_TYPE_SUBJECT;
-       pObject->pszValue[0] = strdup(pMsg->subject);
-       pObject->valueCount = 1;
+       char *temp;
+
+       temp = __msgsvc_vmsg_get_content_value(val);
+       MSG_ERR_RET_VM(NULL == temp, MSG_ERR_INVALID_PARAMETER, "Invalid parameter : read status");
+
+       temp = __msgsvc_vmsg_remove_escape_char(temp);
+
+       if (strcmp(temp, content_name[VMSG_INDICATION_READ_STATUS_READ]) == 0)
+               pMsg->bRead = true;
+       else if (strcmp(temp, content_name[VMSG_INDICATION_READ_STATUS_UNREAD]) == 0)
+               pMsg->bRead = false;
+       else
+               return MSG_ERR_INVALID_PARAMETER;
+
+       MSG_DEBUG("pMsg->bRead = %d", pMsg->bRead);
+       return MSG_SUCCESS;
 }
-       //Insert VBody object
-       INSERT_VBODY_OBJ;
-       pObject->property = VMSG_TYPE_BODY;
 
-       if(pMsg->msgType.mainType == MSG_SMS_TYPE)
-       {
-               if(pMsg->msgType.subType == MSG_NORMAL_SMS)
-               {
-                       if (pMsg->bTextSms == false)
-                       {
-                               char* pFileData = NULL;
-                               AutoPtr<char> buf(&pFileData);
+static inline msg_error_t __msgsvc_vmsg_get_msg_box(MSG_MESSAGE_INFO_S *pMsg, char *val)
+{
+       char *temp;
+
+       temp = __msgsvc_vmsg_get_content_value(val);
+       MSG_ERR_RET_VM(NULL == temp, MSG_ERR_INVALID_PARAMETER, "Invalid parameter : msg box");
+
+       temp = __msgsvc_vmsg_remove_escape_char(temp);
+
+       if (strcmp(temp, content_name[VMSG_INDICATION_MSG_BOX_DRAFT]) == 0) {
+               pMsg->folderId = MSG_DRAFT_ID;
+               pMsg->direction = MSG_DIRECTION_TYPE_MO;
+               pMsg->networkStatus = MSG_NETWORK_NOT_SEND;
+       } else if (strcmp(temp, content_name[VMSG_INDICATION_MSG_BOX_INBOX]) == 0) {
+               pMsg->folderId = MSG_INBOX_ID;
+               pMsg->direction = MSG_DIRECTION_TYPE_MT;
+               pMsg->networkStatus = MSG_NETWORK_RECEIVED;
+       } else if (strcmp(temp, content_name[VMSG_INDICATION_MSG_BOX_SENT]) == 0) {
+               pMsg->folderId = MSG_SENTBOX_ID;
+               pMsg->direction = MSG_DIRECTION_TYPE_MO;
+               pMsg->networkStatus = MSG_NETWORK_SEND_SUCCESS;
+       } else {
+               return MSG_ERR_INVALID_PARAMETER;
+       }
 
-                               int             fileSize = 0;
-                               char*   msgText = NULL;
+       MSG_DEBUG("pMsg->folderId = %d", pMsg->folderId);
+       return MSG_SUCCESS;
+}
 
-                               if (MsgOpenAndReadFile(pMsg->msgData, &pFileData, &fileSize) == false)
-                                       goto __CATCH_FAIL__;
+static inline msg_error_t __msgsvc_vmsg_get_msg_type(MSG_MESSAGE_INFO_S *pMsg, char *val)
+{
+       char *temp;
 
-                               msgText = (char *)calloc(1, fileSize);
-                               memcpy(msgText, pFileData, fileSize);
-                               pObject->numOfBiData = fileSize;
-                               pObject->pszValue[0] = msgText;
-                       }
-                       else
-                       {
-                               pObject->numOfBiData = pMsg->dataSize;
-                               pObject->pszValue[0] = strdup(pMsg->msgText);
-                       }
-                       pObject->valueCount = 1;
-               }
-               else
-                       goto __CATCH_FAIL__;
+       temp = __msgsvc_vmsg_get_content_value(val);
+       MSG_ERR_RET_VM(NULL == temp, MSG_ERR_INVALID_PARAMETER, "Invalid parameter : msg type");
+
+       temp = __msgsvc_vmsg_remove_escape_char(temp);
+
+       if (strcmp(temp, content_name[VMSG_INDICATION_MESSAGE_TYPE_MSG]) == 0) {
+               pMsg->msgType.mainType = MSG_SMS_TYPE;
+               pMsg->msgType.subType = MSG_NORMAL_SMS;
+               pMsg->msgType.classType = MSG_CLASS_NONE;
+       } else if (strcmp(temp, content_name[VMSG_INDICATION_MESSAGE_TYPE_INET]) == 0) {
+               /* To do */
+       } else {
+               return MSG_ERR_INVALID_PARAMETER;
        }
 
-       else if(pMsg->msgType.mainType == MSG_MMS_TYPE)
-       {
-               //Insert VBody for mms raw data;
-               char* pFileData = NULL;
+       MSG_DEBUG("pMsg->msgType.subType = %d", pMsg->msgType.subType);
+       return MSG_SUCCESS;
+}
 
-               int             fileSize = 0;
-               char*   msgText = NULL;
-               char            filePath[MSG_FILEPATH_LEN_MAX] = {0, };
+static inline msg_error_t __msgsvc_vmsg_get_address(MSG_MESSAGE_INFO_S *pMsg, char *prefix, char *val, int* vCardCnt)
+{
+       char *temp;
+       MSG_DEBUG("vCardCnt is : %d", *vCardCnt);
+       if ((pMsg->folderId == MSG_SENTBOX_ID || pMsg->folderId == MSG_DRAFT_ID) && *vCardCnt == 1)
+               return MSG_SUCCESS;
 
-               if(pMsg->msgType.subType == MSG_NOTIFICATIONIND_MMS)
-                       pFileData = MsgOpenAndReadMmsFile(pMsg->msgData, 0, -1, &fileSize);
+       if (pMsg->folderId == MSG_INBOX_ID && *vCardCnt > 1)
+               return MSG_SUCCESS;
 
-               else
-               {
-                       err = MsgStoGetMmsRawFilePath(&dbHandle, pMsg->msgId, filePath);
+       temp = __msgsvc_vmsg_get_content_value(val);
+       MSG_ERR_RET_VM(NULL == temp, MSG_ERR_INVALID_PARAMETER, "Invalid parameter : address");
 
-                       if (err != MSG_SUCCESS)
-                               goto __CATCH_FAIL__;
+       temp = __msgsvc_vmsg_remove_escape_char(temp);
+       MSG_ADDRESS_INFO_S * addrInfo = NULL;
 
-                       pFileData = MsgOpenAndReadMmsFile(filePath, 0, -1, &fileSize);
+       pMsg->nAddressCnt++;
+       MSG_DEBUG("Address is : %s", temp);
+       MSG_DEBUG("Address Cnt : %d", pMsg->nAddressCnt);
+
+
+       if (pMsg->addressList == NULL) {
+               addrInfo = (MSG_ADDRESS_INFO_S *)calloc(1, sizeof(MSG_ADDRESS_INFO_S));
+       } else {
+               addrInfo = (MSG_ADDRESS_INFO_S *)realloc(pMsg->addressList, pMsg->nAddressCnt * sizeof(MSG_ADDRESS_INFO_S));
+       }
+
+       if (addrInfo == NULL) {
+               return MSG_ERR_INVALID_PARAMETER;
+       }
+       pMsg->addressList = addrInfo;
+
+       pMsg->addressList[pMsg->nAddressCnt-1].addressType = MSG_ADDRESS_TYPE_PLMN;
+       pMsg->addressList[pMsg->nAddressCnt-1].recipientType = MSG_RECIPIENTS_TYPE_TO;
+       strncpy(pMsg->addressList[pMsg->nAddressCnt-1].addressVal, temp, MAX_ADDRESS_VAL_LEN);
+       MSG_DEBUG("pMsg->addressList[pMsg->nAddressCnt-1].addressVal = %s", pMsg->addressList[pMsg->nAddressCnt-1].addressVal);
+       return MSG_SUCCESS;
+}
+
+static inline msg_error_t __msgsvc_vmsg_get_msg_date(MSG_MESSAGE_INFO_S *pMsg, char *val)
+{
+       char *temp;
+
+       temp = __msgsvc_vmsg_get_content_value(val);
+       MSG_ERR_RET_VM(NULL == temp, MSG_ERR_INVALID_PARAMETER, "Invalid parameter : date");
+
+       temp = __msgsvc_vmsg_remove_escape_char(temp);
+       MSG_DEBUG("pMsg->displayTime = %s", temp);
+       struct tm displayTime;
+       if ( __msgsvc_vmsg_convert_vdata_to_tm_str(temp, &displayTime))
+               pMsg->displayTime = mktime(&displayTime);
+       else
+               pMsg->displayTime = time(NULL);
+       return MSG_SUCCESS;
+}
+
+static inline msg_error_t __msgsvc_vmsg_get_msg_subject(MSG_MESSAGE_INFO_S *pMsg, char *val)
+{
+       char *temp;
+
+       temp = __msgsvc_vmsg_get_content_value(val);
+       MSG_ERR_RET_VM(NULL == temp, MSG_ERR_INVALID_PARAMETER, "Invalid parameter : subject");
+
+       temp = __msgsvc_vmsg_remove_escape_char(temp);
+
+       if (temp && temp[0] != '\0')
+               strncpy(pMsg->subject, temp, MAX_SUBJECT_LEN);
+       MSG_DEBUG("pMsg->subject = %s", pMsg->subject);
+       return MSG_SUCCESS;
+}
+
+static inline bool __msgsvc_vmsg_get_msg_begin(MSG_MESSAGE_INFO_S *pMsg, char *val, int *vCardCnt)
+{
+       pMsg->encodeType = MSG_ENCODE_AUTO;
+
+       char *temp;
+
+       temp = __msgsvc_vmsg_get_content_value(val);
+       MSG_ERR_RET_VM(NULL == temp, MSG_ERR_INVALID_PARAMETER, "Invalid parameter : body");
+
+       temp = __msgsvc_vmsg_remove_escape_char(temp);
+
+       if (temp && temp[0] != '\0' && strcmp(temp, "VCARD") == 0) {
+               (*vCardCnt)++;
+               return true;
+       }
+       return false;
+}
+
+static inline bool __msgsvc_vmsg_get_msg_end(MSG_MESSAGE_INFO_S *pMsg, char *val)
+{
+       pMsg->encodeType = MSG_ENCODE_AUTO;
+
+       char *temp;
+
+       temp = __msgsvc_vmsg_get_content_value(val);
+       MSG_ERR_RET_VM(NULL == temp, MSG_ERR_INVALID_PARAMETER, "Invalid parameter : body");
+
+       temp = __msgsvc_vmsg_remove_escape_char(temp);
+
+       if (temp && temp[0] != '\0' && strcmp(temp, "VMSG") == 0) {
+               MSG_DEBUG("VMessage decoding completed");
+               return true;
+       } else if (temp && temp[0] != '\0' && strcmp(temp, "VCARD") == 0) {
+               MSG_DEBUG("VMessage decoding completed");
+               return false;
+       }
+       return false;
+}
+
+static inline msg_error_t __msgsvc_vmsg_get_msg(int ver, char *vmsg, MSG_MESSAGE_INFO_S  *record)
+{
+       int type;
+       char *cursor, *new_start, *val, *prefix;
+
+       MSG_MESSAGE_INFO_S *pMsg = record;
+       int vCardCnt = 0;
+       bool isDateAvailable = false;
+       pMsg->msgId = 0;
+       pMsg->threadId = 0;
+       bool end = false;
+
+       cursor = vmsg;
+       while (cursor) {
+               val = NULL;
+               prefix = NULL;
+               bool base64_encoded = false;
+               char *bodyStart = cursor;
+               type =  __msgsvc_vmsg_check_content_type(&cursor);
+
+               if (VMSG_VALUE_NONE == type) {
+                       if (isDateAvailable == true) {
+                               isDateAvailable = false;
+                               /* body decoding */
+                               MSG_DEBUG("Decoding body :");
+                               bodyStart = __msgsvc_vmsg_pass_unsupported(bodyStart);
+                               int i = 0;
+                               char tempMsgText[MAX_MSG_TEXT_LEN + 1] = {0, };
+                               while (bodyStart) {
+                                       if (i >= MAX_MSG_TEXT_LEN)
+                                               break;
+                                       if (*bodyStart == 'E' && *(bodyStart+1) == 'N' && *(bodyStart+2) == 'D' && *(bodyStart+3) == ':') {
+                                               i++;
+                                               break;
+                                       }
+                                       tempMsgText[i] = *bodyStart;
+                                       bodyStart++;
+                                       i++;
+                               }
+                               tempMsgText[i] = '\0';
+                               char * temp = __msgsvc_vmsg_remove_escape_char(tempMsgText);
+                               snprintf(pMsg->msgText, sizeof(pMsg->msgText), "%s", temp);
+                               MSG_DEBUG("pMsg->msgText : %s", pMsg->msgText);
+                               pMsg->dataSize = strlen(pMsg->msgText);
+                               pMsg->bTextSms = true;
+                               base64_encoded = __msgsvc_vmsg_check_base64_encoded(pMsg->msgText);
+
+                               if (base64_encoded) {
+                                       char * decodedText = NULL;
+                                       decodedText = __msgsvc_vmsg_decode_base64_val(pMsg->msgText);
+                                       if (decodedText) {
+                                               strncpy(pMsg->msgText, decodedText, MAX_MSG_TEXT_LEN);
+                                               pMsg->dataSize = strlen(pMsg->msgText);
+                                               free(decodedText);
+                                       } else {
+                                               pMsg->msgText[0] = '\0';
+                                               pMsg->dataSize = 0;
+                                       }
+                               }
+                               g_free(prefix);
+                               g_free(val);
+                               return MSG_SUCCESS;
+                       } else {
+                               new_start =  __msgsvc_vmsg_pass_unsupported(cursor);
+                               if (new_start) {
+                                       cursor = new_start;
+                                       continue;
+                               } else {
+                                       break;
+                               }
+                       }
                }
-               MSG_DEBUG("FILE SIZE IS %d", fileSize);
-               msgText = (char *)calloc(1, fileSize);
-               if(pFileData)
-                       memcpy(msgText, pFileData, fileSize);
-               pObject->numOfBiData = fileSize;
-               pObject->pszValue[0] = msgText;
-               pObject->valueCount = 1;
 
-               if (pFileData) {
-                       free(pFileData);
-                       pFileData = NULL;
+               base64_encoded = __msgsvc_vmsg_check_base64_encoded(cursor);
+
+               new_start = __msgsvc_vmsg_get_val(ver, cursor, &prefix, &val);
+
+               if (NULL == new_start) {
+                       g_free(prefix);
+                       g_free(val);
+                       continue;
+               }
+
+               if (NULL == val) {
+                       cursor = new_start;
+                       g_free(prefix);
+                       g_free(val);
+                       continue;
+               }
+
+               if (base64_encoded) {
+                       char *temp = __msgsvc_vmsg_decode_base64_val(val);
+                       g_free(val);
+                       val = temp;
                }
+               switch (type) {
+               case VMSG_INDICATION_READ_STATUS:
+                       __msgsvc_vmsg_get_read_status(pMsg, val);
+                       break;
+               case VMSG_INDICATION_MSG_BOX:
+                       __msgsvc_vmsg_get_msg_box(pMsg, val);
+                       break;
+               case VMSG_INDICATION_MESSAGE_TYPE:
+                       __msgsvc_vmsg_get_msg_type(pMsg, val);
+                       break;
+               case VMSG_VCARD_TEL:
+                       __msgsvc_vmsg_get_address(pMsg, prefix, val, &vCardCnt);
+                       break;
+               case VMSG_BODY_PROPERTY_DATE:
+                       isDateAvailable = true;
+                       __msgsvc_vmsg_get_msg_date(pMsg, val);
+                       break;
+               case VMSG_BODY_PROPERTY_SUBJECT:
+                       __msgsvc_vmsg_get_msg_subject(pMsg, val);
+                       break;
+               case VMSG_MSG_BEGIN:
+                       end = __msgsvc_vmsg_get_msg_begin(pMsg, val, &vCardCnt);
+                       break;
+               case VMSG_MSG_END:
+                       end = __msgsvc_vmsg_get_msg_end(pMsg, val);
+                       if (end) {
+                               g_free(val);
+                               g_free(prefix);
+                               return MSG_SUCCESS;
+                       } else {
+                               break;
+                       }
+               default:
+                       MSG_ERR("Invalid parameter : __msgsvc_vmsg_check_content_type() Failed(%d)", type);
+                       g_free(val);
+                       g_free(prefix);
+                       return MSG_ERR_INVALID_PARAMETER;
+               }
+               g_free(val);
+               g_free(prefix);
+               cursor = new_start;
        }
 
-       // Insert parameter for base64 encoding
-       MSG_DEBUG("before to start INSERT_PARAM");
-       INSERT_PARAM;
-       pObject->pParam = param;
-       param->parameter = VMSG_PARAM_ENCODING;
-       param->paramValue = VMSG_ENC_PARAM_BASE64;
+       MSG_ERR("Invalid vmsg");
+       return MSG_ERR_INVALID_PARAMETER;
+}
 
-       // Add VCard tree for recipient address information.
-       for(int i = 0; i < pMsg->nAddressCnt; ++i)
-       {
-               pCard = (VTree*)calloc(1, sizeof(VTree));
-               if ( !pCard )
-                       goto __CATCH_FAIL__;
+msg_error_t MsgVMessageDecodeSMS(const char *vmsg_stream, MSG_MESSAGE_INFO_S *pMsg)
+{
+       MSG_BEGIN();
 
-               pCard->treeType = VCARD;
-               pCard->pTop = NULL;
-               pCard->pCur = NULL;
-               pCard->pNext = NULL;
-               pCurrent->pNext = pCard;
-               pCurrent = pCard;
+       int ret, ver;
 
-               INSERT_VCARD_OBJ;
-               pObject->property = VCARD_TYPE_TEL;
-               pObject->pszValue       [0] = strdup(pMsg->addressList[i].addressVal);
-               pObject->valueCount = 1;
-       }
-       MSG_DEBUG("before to start vmsg_encode");
-       encoded_data = vmsg_encode(pMessage);
+       char *vmsg = (char *)vmsg_stream;
 
-       vmsg_free_vtree_memory(pMessage);
-       MSG_END();
-       return encoded_data;
+       char *MMSsend, *MMSretrieve, *MMSnoti;
 
-__CATCH_FAIL__ :
-       vmsg_free_vtree_memory( pMessage );
+       MSG_ERR_RET_VM(NULL == vmsg_stream, MSG_ERR_INVALID_PARAMETER, "Invalid Parameter : vmsg");
 
-       return NULL;
+       vmsg  = __msgsvc_vmsg_check_word(vmsg, "BEGIN:VMSG");
+       MSG_ERR_RET_VM(NULL == vmsg, MSG_ERR_INVALID_PARAMETER, "Invalid parameter : The vmsg is invalid.");
+
+       /* check for mms() */
+       MMSsend = vmsg;
+       MMSretrieve = vmsg;
+       MMSnoti = vmsg;
+
+       MMSsend = __msgsvc_vmsg_check_word(MMSsend, "X-MESSAGE-TYPE:MMS SEND");
+       MSG_ERR_RET_VM(NULL != MMSsend, MSG_ERR_INVALID_MESSAGE, "Invalid parameter : The vmsg format is invalid.");
+
+       MMSretrieve = __msgsvc_vmsg_check_word(MMSretrieve, "X-MESSAGE-TYPE:MMS RETRIEVE");
+       MSG_ERR_RET_VM(NULL != MMSretrieve, MSG_ERR_INVALID_MESSAGE, "Invalid parameter : The vmsg format is invalid.");
+
+       MMSnoti = __msgsvc_vmsg_check_word(MMSnoti, "X-MESSAGE-TYPE:MMS NOTIFICATION");
+       MSG_ERR_RET_VM(NULL != MMSnoti, MSG_ERR_INVALID_MESSAGE, "Invalid parameter : The vmsg format is invalid.");
+
+       /* decode sms() */
+       __msgsvc_vmsg_initial();
+
+       vmsg = __msgsvc_vmsg_check_word(vmsg, "VERSION:1.1");
+       MSG_ERR_RET_VM(NULL == vmsg, MSG_ERR_INVALID_PARAMETER, "Invalid parameter : The vmsg format is invalid.");
+
+       ver = MSGSVC_VMSG_VER_1_1;
+
+       ret = __msgsvc_vmsg_get_msg(ver, vmsg, pMsg);
+       if (MSG_SUCCESS!= ret) {
+               return ret;
+       }
+       MSG_END();
+       return MSG_SUCCESS;
 }
+
+