f74c9827d7d60e4a17a15ef94a8b3f74f039be19
[platform/core/messaging/msg-service.git] / utils / MsgVMessage.cpp
1 /*
2  * Copyright (c) 2014 Samsung Electronics Co., Ltd. All rights reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15 */
16
17 #include <glib.h>
18 #include <errno.h>
19 #include <ctype.h>
20 #include <fcntl.h>
21 #include <unistd.h>
22 #include <unicode/ucnv.h>
23 #include <unicode/ustring.h>
24
25 #include <VMessage.h>
26 #include <VCard.h>
27 #include <time.h>
28
29 #include "MsgMmsTypes.h"
30 #include "MsgContact.h"
31 #include "MsgDebug.h"
32 #include "MsgUtilFile.h"
33 #include "MsgCppTypes.h"
34 #include "MsgVMessage.h"
35 #include "MsgMmsMessage.h"
36 #include "MsgSerialize.h"
37
38 #define VMSG_INIT_LENGTH 1024
39 #define VMSG_ITEM_LENGTH 1024
40 #define MSGSVC_VMSG_FOLDING_LIMIT 75
41
42 #define SMART_STRDUP(src) (src && *src)?strdup(src):NULL
43 #define SAFE_STR(src) (src)?src:""
44
45 #define MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, str) do { \
46         if ((len = __msgsvc_vmsg_append_str(buf, buf_size, len, str, false)) < 0) { \
47                 MSG_ERR("__msgsvc_vmsg_append_str() Failed"); \
48                 return MSG_ERR_MEMORY_ERROR; \
49         } \
50 } while (0)
51
52 #define MSGSVC_VMSG_APPEND_STR_FREE(buf, buf_size, len, str) do { \
53         if ((len = __msgsvc_vmsg_append_str(buf, buf_size, len, str, false)) < 0) { \
54                 MSG_ERR("__msgsvc_vmsg_append_str() Failed"); \
55                 if (str) \
56                         free(str); \
57                 return MSG_ERR_MEMORY_ERROR; \
58         } \
59 } while (0)
60
61 #define MSGSVC_VMSG_APPEND_CONTENT_STR(buf, buf_size, len, content) do { \
62         if ((len = __msgsvc_vmsg_append_str(buf, buf_size, len, content, true)) < 0) { \
63                 MSG_ERR("__msgsvc_vmsg_append_str() Failed"); \
64                 return MSG_ERR_MEMORY_ERROR; \
65         } \
66 } while (0)
67
68
69 #define MSGSVC_VMSG_APPEND_CONTENT(buf, buf_size, len, content) do { \
70         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, ";CHARSET=UTF-8"); \
71         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, ":"); \
72         MSGSVC_VMSG_APPEND_CONTENT_STR(buf, buf_size, len, content); \
73         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF); \
74 } while (0)
75
76 enum {
77         CTSVC_VCARD_VER_NONE,
78         CTSVC_VCARD_VER_2_1,
79         CTSVC_VCARD_VER_3_0,
80         CTSVC_VCARD_VER_4_0,
81 };
82
83 enum {
84         MSGSVC_VMSG_VER_NONE,
85         MSGSVC_VMSG_VER_1_1,
86         MSGSVC_VMSG_VER_3_0
87 };
88
89
90 enum {
91          /* vMessage */
92         VMSG_VALUE_NONE = 0,
93         BEGIN_VMSG = 1,
94         VERSION_VMSG = 2,
95         BEGIN_VCARD = 3,
96         VERSION_VCARD = 4,
97         END_VCARD = 5,
98         BEGIN_VENV = 6,
99         BEGIN_VBODY = 7,
100         END_VBODY = 8,
101         END_VENV = 9,
102         END_VMSG = 10,
103
104         FNAME_VCARD = 11 ,
105         NAME_VCARD = 12,
106         TEL_VCARD = 13,
107         TEL_VCARD_CELL = 14,
108
109         DATE_VMSG = 15,
110         SUBJECT_VMSG = 16,
111
112         FNAME_UTF8_VCARD = 17,
113         NAME_UTF8_VCARD = 18,
114
115         /* Encodings */
116         VMSG_ATTR_ENCODING_QP = 19,
117         VMSG_ATTR_ENCODING_BASE64_V21 = 20,
118         VMSG_ATTR_ENCODING_BASE64_V30 = 21,
119
120         /* Message type indication */
121         VMSG_INDICATION_MESSAGE_TYPE = 22,
122         VMSG_INDICATION_MESSAGE_TYPE_INET = 23,
123         VMSG_INDICATION_MESSAGE_TYPE_MSG = 24,
124
125         /* Read status indication */
126         VMSG_INDICATION_READ_STATUS = 25,
127         VMSG_INDICATION_READ_STATUS_READ = 26,
128         VMSG_INDICATION_READ_STATUS_UNREAD = 27,
129
130         /* Mailbox status indication */
131         VMSG_INDICATION_MSG_BOX = 28,
132         VMSG_INDICATION_MSG_BOX_SENT = 29,
133         VMSG_INDICATION_MSG_BOX_INBOX = 30,
134         VMSG_INDICATION_MSG_BOX_DRAFT = 31,
135
136         /* Character set */
137         VMSG_ATTR_CHARSET_PROPERTY = 32,
138
139         /* Language */
140         VMSG_ATTR_LANGUAGE_PROPERTY = 33,
141         VMSG_DATA_SEPARATOR = 34,
142
143         VMSG_BODY_PROPERTY_DATE = 35,
144         VMSG_BODY_PROPERTY_SUBJECT = 36,
145         VMSG_BODY_PROPERTY_FROM = 37,
146         VMSG_BODY_PROPERTY_TO = 38,
147
148         KEY_BODY = 39,
149         KEY_DATE = 40,
150
151         /* DECODER */
152         VMSG_VCARD_TEL = 41,
153         VMSG_MSG_BEGIN = 42,
154         VMSG_MSG_END = 43,
155         VMSG_MAXIMUM_VALUE = 44,
156 };
157
158 static const char *content_name[VMSG_MAXIMUM_VALUE+1] = {0};
159 const char *MSGSVC_CRLF = "\r\n";
160 bool needCharset = false;
161
162 static void __msgsvc_vmsg_initial(void)
163 {
164         if (NULL == *content_name) {
165                 /* vMessage */
166                 content_name[BEGIN_VMSG] = "BEGIN:VMSG";
167                 content_name[VERSION_VMSG] = "VERSION:1.1";
168                 content_name[BEGIN_VCARD] = "BEGIN:VCARD";
169                 content_name[VERSION_VCARD] = "VERSION:2.1";
170                 content_name[END_VCARD] = "END:VCARD";
171                 content_name[BEGIN_VENV] = "BEGIN:VENV";
172                 content_name[BEGIN_VBODY] = "BEGIN:VBODY";
173                 content_name[END_VBODY] = "END:VBODY";
174                 content_name[END_VENV] = "END:VENV";
175                 content_name[END_VMSG] = "END:VMSG";
176
177                 content_name[FNAME_VCARD] = "FN:";
178                 content_name[NAME_VCARD] = "N:";
179                 content_name[TEL_VCARD] = "TEL;";
180                 content_name[TEL_VCARD_CELL] = "CELL:";
181
182                 content_name[DATE_VMSG] = "Date:";
183                 content_name[SUBJECT_VMSG] = "Subject:";
184
185                 content_name[FNAME_UTF8_VCARD] = "FN;CHARSET=UTF-8:";
186                 content_name[NAME_UTF8_VCARD] = "N;CHARSET=UTF-8:";
187
188                 /* Encodings */
189                 content_name[VMSG_ATTR_ENCODING_QP] = "ENCODING=QUOTED-PRINTABLE";
190                 content_name[VMSG_ATTR_ENCODING_BASE64_V21] = "ENCODING=BASE64";
191                 content_name[VMSG_ATTR_ENCODING_BASE64_V30] = "ENCODING=b";
192
193                 /* Message type indication */
194                 content_name[VMSG_INDICATION_MESSAGE_TYPE] = "X-IRMC-TYPE";
195                 content_name[VMSG_INDICATION_MESSAGE_TYPE_INET] = "INET";
196                 content_name[VMSG_INDICATION_MESSAGE_TYPE_MSG] = "MSG";
197
198                 /* Read status indication */
199                 content_name[VMSG_INDICATION_READ_STATUS] = "X-IRMC-STATUS";
200                 content_name[VMSG_INDICATION_READ_STATUS_READ] = "READ";
201                 content_name[VMSG_INDICATION_READ_STATUS_UNREAD] =  "UNREAD";
202
203                 /* Mailbox status indication */
204                 content_name[VMSG_INDICATION_MSG_BOX] = "X-IRMC-BOX";
205                 content_name[VMSG_INDICATION_MSG_BOX_SENT] = "SENT";
206                 content_name[VMSG_INDICATION_MSG_BOX_INBOX] = "INBOX";
207                 content_name[VMSG_INDICATION_MSG_BOX_DRAFT] =  "DRAFT";
208
209                 /* Character set */
210                 content_name[VMSG_ATTR_CHARSET_PROPERTY] = "CHARSET";
211
212                 /* Language */
213                 content_name[VMSG_ATTR_LANGUAGE_PROPERTY] =  "LANGUAGE";
214                 content_name[VMSG_DATA_SEPARATOR] = ":";
215
216                 content_name[VMSG_BODY_PROPERTY_DATE] = "Date";
217                 content_name[VMSG_BODY_PROPERTY_SUBJECT] = "Subject";
218                 content_name[VMSG_BODY_PROPERTY_FROM] = "From";
219                 content_name[VMSG_BODY_PROPERTY_TO] = "To";
220
221                 content_name[KEY_BODY] = "body";
222                 content_name[KEY_DATE] = "date";
223
224                 content_name[VMSG_VCARD_TEL] = "TEL";
225                 content_name[VMSG_MSG_BEGIN] = "BEGIN";
226                 content_name[VMSG_MSG_END] = "END";
227                 content_name[VMSG_MAXIMUM_VALUE] = "MAX";
228         }
229 };
230
231 static int __msgsvc_vmsg_append_str(char **buf, int *buf_size, int len, const char *str, bool need_conversion)
232 {
233         int len_temp = 0;
234         char *tmp = NULL;
235         const char *safe_str = SAFE_STR(str);
236         int str_len = 0;
237         bool need_realloc = false;
238
239         str_len = strlen(safe_str);
240         while ((*buf_size-len) < (str_len+1)) {
241                 *buf_size = *buf_size * 2;
242                 need_realloc = true;
243         }
244
245         if (need_realloc) {
246                 if (NULL == (tmp = (char *)realloc(*buf, *buf_size)))
247                         return -1;
248                 else
249                         *buf = tmp;
250         }
251
252         if (need_conversion) {
253                 const char *s = safe_str;
254                 char *r = (char *)(*buf+len);
255
256                 while (*s) {
257                         switch (*s) {
258                         case '\r':
259                                 if (*(s+1) && '\n' == *(s+1)) {
260                                         s++;
261                                         *r = '\\';
262                                         r++;
263                                         *r = 'n';
264                                 }
265                                 else {
266                                         *r = *s;
267                                 }
268                                 break;
269                         case '\n':
270                                 *r = '\\';
271                                 r++;
272                                 str_len++;
273                                 if (*buf_size < str_len+len+1) {
274                                         *buf_size = *buf_size * 2;
275                                         if (NULL == (tmp = (char *)realloc(*buf, *buf_size)))
276                                                 return -1;
277                                         else {
278                                                 int pos_temp = r-(*buf+len);
279                                                 *buf = tmp;
280                                                 r = (char *)(*buf+len+pos_temp);
281                                         }
282                                 }
283                                 *r = 'n';
284                                 break;
285                         case ';':
286                         case ':':
287                         case ',':
288                         case '<':
289                         case '>':
290                         case '\\':
291                                 *r = '\\';
292                                 r++;
293                                 str_len++;
294                                 if (*buf_size < str_len+len+1) {
295                                         *buf_size = *buf_size * 2;
296                                         if (NULL == (tmp = (char *)realloc(*buf, *buf_size)))
297                                                 return -1;
298                                         else {
299                                                 int pos_temp = r-(*buf+len);
300                                                 *buf = tmp;
301                                                 r = (char *)(*buf+len+pos_temp);
302                                         }
303                                 }
304                                 *r = *s;
305                                 break;
306                         case 0xA1:
307                                 if (*(s+1) && 0xAC == *(s+1)) { /* en/em backslash */
308                                         *r = '\\';
309                                         r++;
310                                         str_len++;
311                                         if (*buf_size < str_len+len+1) {
312                                                 *buf_size = *buf_size * 2;
313                                                 if (NULL == (tmp = (char *)realloc(*buf, *buf_size)))
314                                                         return -1;
315                                                 else {
316                                                         int pos_temp = r-(*buf+len);
317                                                         *buf = tmp;
318                                                         r = (char *)(*buf+len+pos_temp);
319                                                 }
320                                         }
321
322                                         *r = *s;
323                                         r++;
324                                         s++;
325                                         if (*buf_size < str_len+len+1) {
326                                                 *buf_size = *buf_size * 2;
327                                                 if (NULL == (tmp = (char *)realloc(*buf, *buf_size)))
328                                                         return -1;
329                                                 else {
330                                                         int pos_temp = r-(*buf+len);
331                                                         *buf = tmp;
332                                                         r = (char *)(*buf+len+pos_temp);
333                                                 }
334                                         }
335                                         *r = *s;
336                                 }
337                                 else {
338                                         *r = *s;
339                                 }
340                                 break;
341                         case 0x81:
342                                 if (*(s+1) && 0x5F == *(s+1)) { /* en/em backslash */
343                                         *r = '\\';
344                                         r++;
345                                         str_len++;
346                                         if (*buf_size < str_len+len+1) {
347                                                 *buf_size = *buf_size * 2;
348                                                 if (NULL == (tmp = (char *)realloc(*buf, *buf_size)))
349                                                         return -1;
350                                                 else {
351                                                         int pos_temp = r-(*buf+len);
352                                                         *buf = tmp;
353                                                         r = (char *)(*buf+len+pos_temp);
354                                                 }
355                                         }
356
357                                         *r = *s;
358                                         r++;
359                                         s++;
360                                         if (*buf_size < str_len+len+1) {
361                                                 *buf_size = *buf_size * 2;
362                                                 if (NULL == (tmp = (char *)realloc(*buf, *buf_size)))
363                                                         return -1;
364                                                 else {
365                                                         int pos_temp = r-(*buf+len);
366                                                         *buf = tmp;
367                                                         r = (char *)(*buf+len+pos_temp);
368                                                 }
369                                         }
370                                         *r = *s;
371                                 }
372                                 else {
373                                         *r = *s;
374                                 }
375                                 break;
376                         default:
377                                 *r = *s;
378                                 break;
379                         }
380                         r++;
381                         s++;
382                 }
383                 len_temp = str_len;
384         }
385         else {
386                 len_temp = snprintf(*buf+len, *buf_size-len+1, "%s", safe_str);
387         }
388         len += len_temp;
389         return len;
390 }
391
392
393 /*==================================================================================================
394                                      DEFINES
395 ==================================================================================================*/
396 #define INSERT_VMSG_OBJ pObject = (VObject*)calloc(1, sizeof(VObject)); \
397                                       if ( !pObject )\
398 {\
399    vmsg_free_vtree_memory(pMessage);\
400    return false;\
401 }\
402 if (pMessage->pTop == NULL)\
403 {\
404    pMessage->pTop = pObject;\
405 }\
406 else\
407 {\
408    pMessage->pCur->pSibling = pObject;\
409 }\
410 pMessage->pCur = pObject;
411
412
413 #define INSERT_VBODY_OBJ pObject = (VObject*)calloc(1, sizeof(VObject));        \
414                                       if ( !pObject )\
415 {\
416    vmsg_free_vtree_memory(pMessage);\
417    return false;\
418 }\
419 if (pBody->pTop == NULL)\
420 {\
421    pBody->pTop = pObject;\
422 }\
423 else\
424 {\
425    pBody->pCur->pSibling = pObject;\
426 }\
427 pBody->pCur = pObject;
428
429
430 #define INSERT_VCARD_OBJ pObject = (VObject*)calloc(1, sizeof(VObject));        \
431                                       if ( !pObject )\
432 {\
433    vmsg_free_vtree_memory(pMessage);\
434    return false;\
435 }\
436 if (pCard->pTop == NULL)\
437 {\
438    pCard->pTop = pObject;\
439 }\
440 else\
441 {\
442    pCard->pCur->pSibling = pObject;\
443 }\
444 pCard->pCur = pObject;
445
446
447 #define INSERT_PARAM  param = (VParam*)calloc(1, sizeof(VParam));\
448                              if (!param)\
449 {\
450    vmsg_free_vtree_memory(pMessage);\
451    if (pObject != NULL)\
452    {\
453       free(pObject);\
454       pObject = NULL;\
455    }\
456    return false;\
457 }
458
459
460 /*==================================================================================================
461                                      FUNCTION IMPLEMENTATION
462 ==================================================================================================*/
463
464 char* _convert_tm_to_vdata_str(const struct tm * tm)
465 {
466         char str[17] = {0, };
467
468         snprintf(str, 17, "%04d%02d%02dT%02d%02d%02dZ",
469                 tm->tm_year + 1900,
470                 tm->tm_mon +1,
471                 tm->tm_mday,
472                 tm->tm_hour,
473                 tm->tm_min,
474                 tm->tm_sec);
475
476         return strdup(str);
477 }
478
479 bool _convert_vdata_str_to_tm(const char* szText, struct tm * tm)
480 {
481    if (szText == NULL) return false;
482    if (strlen(szText) < 15) return false;
483    if (szText[8] != 'T') return false;
484
485    char szBuff[8]={0};
486    memset(tm, 0, sizeof(struct tm));
487
488    /* year, month, day */
489    memcpy(szBuff, &(szText[0]), 4);
490    szBuff[4] = '\0';
491    tm->tm_year = atol(szBuff) - 1900;
492    if ((tm->tm_year > 137) || (tm->tm_year < 0))
493       tm->tm_year = 0;
494
495    memcpy(szBuff, &(szText[4]), 2);
496    szBuff[2] = '\0';
497    tm->tm_mon = atol(szBuff)-1;
498    if ((tm->tm_mon > 11) || (tm->tm_mon < 0))
499       tm->tm_mon = 11;
500
501    memcpy(szBuff, &(szText[6]), 2);
502    szBuff[2] = '\0';
503    tm->tm_mday = atol(szBuff);
504    if ((tm->tm_mday > 31) || (tm->tm_mday < 1))
505       tm->tm_mday = 31;
506
507    /* hour, minute, second */
508    memcpy(szBuff, &(szText[9]), 2);
509    szBuff[2] = '\0';
510    tm->tm_hour = atol(szBuff);
511    if ((tm->tm_hour > 23) || (tm->tm_hour < 0))
512       tm->tm_hour = 23;
513
514    memcpy(szBuff, &(szText[11]), 2);
515    szBuff[2] = '\0';
516    tm->tm_min = atol(szBuff);
517    if ((tm->tm_min > 59) || (tm->tm_min < 0))
518       tm->tm_min = 59;
519
520    memcpy(szBuff, &(szText[13]), 2);
521    szBuff[2] = '\0';
522    tm->tm_sec = atol(szBuff);
523    if ((tm->tm_sec > 59) || (tm->tm_sec < 0))
524       tm->tm_sec = 59;
525
526    return true;
527 }
528
529 int msgsvc_check_utf8(char c)
530 {
531         if ((c & 0xff) < (128 & 0xff))
532                 return 1;
533         else if ((c & (char)0xe0) == (char)0xc0)
534                 return 2;
535         else if ((c & (char)0xf0) == (char)0xe0)
536                 return 3;
537         else if ((c & (char)0xf8) == (char)0xf0)
538                 return 4;
539         else if ((c & (char)0xfc) == (char)0xf8)
540                 return 5;
541         else if ((c & (char)0xfe) == (char)0xfc)
542                 return 6;
543         else
544                 return MSG_ERR_INVALID_PARAMETER;
545 }
546
547 char* __msgsvc_vmsg_convert_tm_to_vdata_str(struct tm * tm)
548 {
549         char str[22] = {0, };
550         char APM[3] = {0, };
551         char month[15] = {0, };
552         int mon = 0;
553         int hour = 0;
554         mon = tm->tm_mon + 1;
555
556         if (tm->tm_hour >= 12)
557                 strcpy(APM, "PM");
558         else
559                 strcpy(APM, "AM");
560
561         if (tm->tm_hour > 12)
562                 hour = tm->tm_hour - 12;
563         else
564                 hour = tm->tm_hour;
565
566         switch(mon) {
567                 case 1:
568                         strcpy(month, "Jan");
569                         break;
570                 case 2:
571                         strcpy(month, "Feb");
572                         break;
573                 case 3:
574                         strcpy(month, "Mar");
575                         break;
576                 case 4:
577                         strcpy(month, "Apr");
578                         break;
579                 case 5:
580                         strcpy(month, "May");
581                         break;
582                 case 6:
583                         strcpy(month, "Jun");
584                         break;
585                 case 7:
586                         strcpy(month, "Jul");
587                         break;
588                 case 8:
589                         strcpy(month, "Aug");
590                         break;
591                 case 9:
592                         strcpy(month, "Sep");
593                         break;
594                 case 10:
595                         strcpy(month, "Oct");
596                         break;
597                 case 11:
598                         strcpy(month, "Nov");
599                         break;
600                 case 12:
601                         strcpy(month, "Dec");
602                         break;
603                 default:
604                         MSG_DEBUG("invalid month number");
605                 break;
606         }
607
608         snprintf(str, 22, "%d:%02d%s, %04d %s %d",
609                 hour,
610                 tm->tm_min,
611                 APM,
612                 tm->tm_year + 1900,
613                 month,
614                 tm->tm_mday);
615
616         return strdup(str);
617 }
618 static inline int __msgsvc_vmsg_add_folding(char **buf, int *buf_size, int buf_len)
619 {
620         int char_len = 0;
621         char *buf_copy = NULL;
622         int len, result_len;
623         char *r;
624         const char *s;
625         bool content_start = false;
626         bool encode_64 = false;
627
628         buf_copy = (char *)calloc(1, *buf_size);
629
630         s = *buf;
631         r = buf_copy;
632         len = result_len = 0;
633
634         while (*s) {
635                 if (*buf_size < result_len + 5) {
636                         char *tmp = NULL;
637                         *buf_size = *buf_size + 1000;
638                         if (NULL == (tmp = (char *)realloc(buf_copy, *buf_size))) {
639                                 free(buf_copy);
640                                 return -1;
641                         }
642                         else {
643                                 buf_copy = tmp;
644                                 r = (buf_copy + result_len);
645                         }
646                 }
647
648                 if (false == content_start) {
649                         if (':' == *s)
650                                 content_start = true;
651                         else if (0 == strncmp(s, "ENCODING=BASE64", strlen("ENCODING=BASE64")))
652                                 encode_64 = true;
653                 }
654
655                 if ('\r' == *s)
656                         len--;
657                 else if ('\n' == *s) {
658                         len = -1;
659                         char_len = 0;
660                         content_start = false;
661                         encode_64 = false;
662                 }
663
664                 if (0 == char_len) {
665                         if (false == encode_64)
666                                 char_len = msgsvc_check_utf8(*s);
667
668                         if (MSGSVC_VMSG_FOLDING_LIMIT <= len + char_len) {
669                                 *r = '\r';
670                                 r++;
671                                 *r = '\n';
672                                 r++;
673                                 *r = ' ';
674                                 r++;
675                                 len = 1;
676                                 result_len += 3;
677                         }
678                 }
679
680                 if (char_len)
681                         char_len--;
682
683                 *r = *s;
684                 r++;
685                 s++;
686                 len++;
687                 result_len++;
688         }
689         *r = '\0';
690         free(*buf);
691         *buf = buf_copy;
692         return result_len;
693 }
694
695 static inline int __msgsvc_vmsg_append_start_vmsg_1_1(char **buf, int *buf_size, int len)
696 {
697         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[BEGIN_VMSG]);
698         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
699         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[VERSION_VMSG]);
700         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
701         return len;
702 }
703
704 static inline int __msgsvc_vmsg_append_end_vmsg(char **buf, int *buf_size, int len)
705 {
706         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[END_VMSG]);
707         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
708         return len;
709 }
710
711 static inline int __msgsvc_vmsg_append_read_status(MSG_MESSAGE_INFO_S *pMsg, char **buf, int *buf_size, int len)
712 {
713         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[VMSG_INDICATION_READ_STATUS]);
714         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[VMSG_DATA_SEPARATOR]);
715         if (pMsg->bRead) {
716                 MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[VMSG_INDICATION_READ_STATUS_READ]);
717                 MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
718         } else {
719                 MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[VMSG_INDICATION_READ_STATUS_UNREAD]);
720                 MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
721         }
722         return len;
723 }
724 static inline int __msgsvc_vmsg_append_box_type(MSG_MESSAGE_INFO_S *pMsg, char **buf, int *buf_size, int len)
725 {
726         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[VMSG_INDICATION_MSG_BOX]);
727         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[VMSG_DATA_SEPARATOR]);
728         switch(pMsg->folderId) {
729                 case MSG_INBOX_ID:
730                         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[VMSG_INDICATION_MSG_BOX_INBOX]);
731
732                         break;
733                 case MSG_SENTBOX_ID:
734                         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[VMSG_INDICATION_MSG_BOX_SENT]);
735
736                         break;
737                 case MSG_DRAFT_ID:
738                         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[VMSG_INDICATION_MSG_BOX_DRAFT]);
739                         break;
740                 default:
741                         /* Discard User Defined, outbox or Spam folder's messages. */
742                         MSG_DEBUG("Invalid or unhandled msg box");
743         }
744         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
745         return len;
746 }
747
748 static inline int __msgsvc_vmsg_append_msg_type(MSG_MESSAGE_INFO_S *pMsg, char **buf, int *buf_size, int len)
749 {
750         /* TO DO check with msg text contains Only PrintableAscii if true then else handle INET_TYPE */
751         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[VMSG_INDICATION_MESSAGE_TYPE]);
752         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[VMSG_DATA_SEPARATOR]);
753         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[VMSG_INDICATION_MESSAGE_TYPE_MSG]);
754         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
755         return len;
756 }
757
758 static inline int __msgsvc_vmsg_append_origin_address_vcard(MSG_MESSAGE_INFO_S *pMsg, char **buf, int *buf_size, int len)
759 {
760         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[BEGIN_VCARD]);
761         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
762         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[VERSION_VCARD]);
763         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
764         char originAddress[MAX_ADDRESS_VAL_LEN + 1] = {0, };
765         bool isDisplayName = false;
766
767         if (pMsg->folderId == MSG_INBOX_ID) {
768                 strcpy(originAddress, pMsg->addressList[0].addressVal);
769         }
770
771         needCharset = true; /* as per android */
772
773         if (strlen(originAddress) > 0) {
774                 MSG_CONTACT_INFO_S contactInfo;
775                 memset(&contactInfo, 0x00, sizeof(MSG_CONTACT_INFO_S));
776
777                 if (MsgGetContactInfo(&(pMsg->addressList[0]), &contactInfo) != MSG_SUCCESS) {
778                         MSG_WARN("MsgGetContactInfo() fail.");
779                 }
780                 snprintf(pMsg->addressList[0].displayName, sizeof(pMsg->addressList[0].displayName), "%s", contactInfo.firstName);
781                 if (pMsg->addressList[0].displayName[0] != '\0')
782                         isDisplayName = true;
783                 if (needCharset && isDisplayName) {
784                         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[FNAME_UTF8_VCARD]);
785                         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, pMsg->addressList->displayName);
786                         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
787                         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[NAME_UTF8_VCARD]);
788                         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, pMsg->addressList->displayName);
789                         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
790                 } else {
791                         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[FNAME_VCARD]);
792                         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, pMsg->addressList->displayName);
793                         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
794                         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[NAME_VCARD]);
795                         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, pMsg->addressList->displayName);
796                         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
797                 }
798                 if (MsgIsNumber(originAddress)) {
799                         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[TEL_VCARD]);
800                         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[TEL_VCARD_CELL]);
801                         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, originAddress);
802                         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
803                 }
804         } else {
805                 MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[FNAME_VCARD]);
806                 MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
807                 MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[NAME_VCARD]);
808                 MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
809         }
810
811
812         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[END_VCARD]);
813         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
814         return len;
815 }
816
817 static inline int __msgsvc_vmsg_append_recipient_address_vcard(MSG_MESSAGE_INFO_S *pMsg, char **buf, int *buf_size, int len)
818 {
819         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[BEGIN_VCARD]);
820         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
821         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[VERSION_VCARD]);
822         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
823
824         needCharset = true; /* as per android */
825
826         for (int i = 0; i < pMsg->nAddressCnt; ++i) {
827                 char originAddress[MAX_ADDRESS_VAL_LEN + 1] = {0, };
828                 bool isDisplayName = false;
829
830                 if (pMsg->folderId == MSG_SENTBOX_ID) {
831                         strcpy(originAddress, pMsg->addressList[0].addressVal);
832                 }
833
834                 if (strlen(originAddress) > 0) {
835                         MSG_CONTACT_INFO_S contactInfo;
836                         memset(&contactInfo, 0x00, sizeof(MSG_CONTACT_INFO_S));
837
838                         if (MsgGetContactInfo(&(pMsg->addressList[i]), &contactInfo) != MSG_SUCCESS) {
839                                 MSG_WARN("MsgGetContactInfo() fail.");
840                         }
841                         snprintf(pMsg->addressList[i].displayName, sizeof(pMsg->addressList[i].displayName), "%s", contactInfo.firstName);
842                         if (pMsg->addressList[i].displayName[0] != '\0')
843                                 isDisplayName = true;
844                         if (needCharset && isDisplayName) {
845                                 MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[FNAME_UTF8_VCARD]);
846                                 MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, pMsg->addressList[i].displayName);
847                                 MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
848                                 MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[NAME_UTF8_VCARD]);
849                                 MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, pMsg->addressList[i].displayName);
850                                 MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
851                         } else {
852                                 MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[FNAME_VCARD]);
853                                 MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, pMsg->addressList[i].displayName);
854                                 MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
855                                 MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[NAME_VCARD]);
856                                 MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, pMsg->addressList[i].displayName);
857                                 MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
858                         }
859                         if (MsgIsNumber(originAddress)) {
860                                 MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[TEL_VCARD]);
861                                 MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[TEL_VCARD_CELL]);
862                                 MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, originAddress);
863                                 MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
864                         }
865                 } else {
866                         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[FNAME_VCARD]);
867                         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
868                         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[NAME_VCARD]);
869                         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
870                 }
871         }
872
873         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[END_VCARD]);
874         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
875
876         return len;
877 }
878
879 static inline int __msgsvc_vmsg_append_msg_body(MSG_MESSAGE_INFO_S *pMsg, char **buf, int *buf_size, int len)
880 {
881         struct tm       display_time;
882
883         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[BEGIN_VENV]);
884         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
885
886         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[BEGIN_VBODY]);
887         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
888
889         /* Date: */
890         tzset();
891         localtime_r(&(pMsg->displayTime), &display_time);
892         char *msgDate = __msgsvc_vmsg_convert_tm_to_vdata_str(&display_time);
893
894         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[VMSG_BODY_PROPERTY_DATE]);
895         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[VMSG_DATA_SEPARATOR]);
896         if (msgDate !=NULL) {
897                 MSGSVC_VMSG_APPEND_STR_FREE(buf, buf_size, len, msgDate);
898                 MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
899                 g_free(msgDate);
900         }
901
902         /* Subject: */
903         if (pMsg->subject[0] != '\0') {
904                 MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[VMSG_BODY_PROPERTY_SUBJECT]);
905                 MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[VMSG_DATA_SEPARATOR]);
906                 MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, pMsg->subject);
907                 MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
908         }
909
910         /* body: */
911         if(pMsg->msgType.mainType == MSG_SMS_TYPE) {
912                 if(pMsg->msgType.subType == MSG_NORMAL_SMS) {
913                         if (pMsg->bTextSms == false) {
914                                 char* pFileData = NULL;
915                                 unique_ptr<char*, void(*)(char**)> buff(&pFileData, unique_ptr_deleter);
916
917                                 int             fileSize = 0;
918                                 char*   msgText = NULL;
919
920                                 if (MsgOpenAndReadFile(pMsg->msgData, &pFileData, &fileSize) == false)
921                                         return len;
922
923                                 msgText = (char *)calloc(1, fileSize);
924                                 memcpy(msgText, pFileData, fileSize);
925                                 MSGSVC_VMSG_APPEND_STR_FREE(buf, buf_size, len, msgText);
926                                 g_free(msgText);
927                         } else {
928                                 MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, pMsg->msgText);
929                         }
930                 }
931         }
932
933         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
934
935         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[END_VBODY]);
936         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
937
938         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[END_VENV]);
939         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
940         return len;
941 }
942
943 static inline int __msgsvc_vmsg_append_msg_envelope(MSG_MESSAGE_INFO_S *pMsg, char **buf, int *buf_size, int len)
944 {
945         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[BEGIN_VENV]);
946         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
947
948         len = __msgsvc_vmsg_append_recipient_address_vcard(pMsg, buf, buf_size, len);
949         MSG_ERR_RET_VM(len < 0, len, "Invalid length : vcard");
950
951         len = __msgsvc_vmsg_append_msg_body(pMsg, buf, buf_size, len);
952         MSG_ERR_RET_VM(len < 0, len, "Invalid length : body");
953
954         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[END_VENV]);
955         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
956         return len;
957 }
958
959 static inline int __msgsvc_vmsg_append_msg(MSG_MESSAGE_INFO_S *pMsg, char **buf, int *buf_size, int len)
960 {
961         len = __msgsvc_vmsg_append_read_status(pMsg, buf, buf_size, len);
962         MSG_ERR_RET_VM(len < 0, len, "Invalid length : read status");
963
964         len = __msgsvc_vmsg_append_box_type(pMsg, buf, buf_size, len);
965         MSG_ERR_RET_VM(len < 0, len, "Invalid length : box type");
966
967         len = __msgsvc_vmsg_append_msg_type(pMsg, buf, buf_size, len);
968         MSG_ERR_RET_VM(len < 0, len, "Invalid length : msg type");
969
970         len = __msgsvc_vmsg_append_origin_address_vcard(pMsg, buf, buf_size, len);
971         MSG_ERR_RET_VM(len < 0, len, "Invalid length : origin address");
972
973         len = __msgsvc_vmsg_append_msg_envelope(pMsg, buf, buf_size, len);
974         MSG_ERR_RET_VM(len < 0, len, "Invalid length : envelop");
975
976         return len;
977 }
978
979 char *MsgVMessageEncode(MSG_MESSAGE_INFO_S *pMsg)
980 {
981         MSG_BEGIN();
982
983         VObject*                pObject = NULL;
984         VParam*         param = NULL;
985         VTree *         pBody = NULL;
986         VTree *         pCard = NULL;
987         VTree *         pCurrent = NULL;
988         struct tm       display_time;
989         char*           encoded_data = NULL;
990
991         VTree* pMessage = NULL;
992
993         /* to encode sms */
994         if (pMsg->msgType.mainType == MSG_SMS_TYPE && pMsg->msgType.subType == MSG_NORMAL_SMS) {
995                 return MsgVMessageEncodeSMS(pMsg);
996         }
997
998         /* to encode mms */
999         if (pMessage == NULL) {
1000                 pMessage = (VTree *)malloc(sizeof(VTree));
1001                 if (!pMessage) {
1002                         return NULL;
1003                 }
1004                 pMessage->treeType = VMESSAGE;
1005                 pMessage->pTop = NULL;
1006                 pMessage->pCur = NULL;
1007                 pMessage->pNext = NULL;
1008         }
1009                 pCurrent = pMessage;
1010
1011         /* Insert VObject (X-MESSAGE-TYPE) to VMessage tree */
1012         INSERT_VMSG_OBJ;
1013
1014         pObject->property = VMSG_TYPE_MSGTYPE;
1015
1016         if (pMsg->msgType.mainType == MSG_MMS_TYPE && (pMsg->msgType.subType == MSG_SENDREQ_MMS || pMsg->msgType.subType == MSG_SENDCONF_MMS))
1017                 pObject->pszValue[0] = strdup("MMS SEND");
1018 #if 0
1019         else if (pMsg->msgType.mainType == MSG_MMS_TYPE && pMsg->msgType.subType == MSG_NOTIFICATIONIND_MMS)
1020                 pObject->pszValue[0] = strdup("MMS NOTIFICATION");
1021 #endif
1022
1023         else if (pMsg->msgType.mainType == MSG_MMS_TYPE && (pMsg->msgType.subType == MSG_RETRIEVE_AUTOCONF_MMS || pMsg->msgType.subType == MSG_RETRIEVE_MANUALCONF_MMS))
1024                 pObject->pszValue[0] = strdup("MMS RETRIEVED");
1025
1026         else
1027                 goto __CATCH_FAIL__;
1028
1029         pObject->valueCount = 1;
1030
1031
1032         /* Insert VObject (X-IRMC-BOX) to VMessate tree */
1033         INSERT_VMSG_OBJ;
1034
1035         pObject->property = VMSG_TYPE_MSGBOX;
1036
1037         switch(pMsg->folderId) {
1038                 case MSG_INBOX_ID:
1039                         pObject->pszValue[0] = strdup("INBOX");
1040                         break;
1041                 case MSG_OUTBOX_ID:
1042                         pObject->pszValue[0] = strdup("OUTBOX");
1043                         break;
1044                 case MSG_SENTBOX_ID:
1045                         pObject->pszValue[0] = strdup("SENTBOX");
1046                         break;
1047                 case MSG_DRAFT_ID:
1048                         pObject->pszValue[0] = strdup("DRAFTBOX");
1049                         break;
1050                 default:
1051                         /* Discard User Defined or Spam folder's messages. */
1052                         goto __CATCH_FAIL__;
1053         }
1054         pObject->valueCount = 1;
1055
1056
1057         /* Insert VObject (X-SS-DT) to VMessage tree */
1058         INSERT_VMSG_OBJ;
1059
1060         pObject->property = VMSG_TYPE_DATE;
1061         tzset();
1062         localtime_r(&(pMsg->displayTime), &display_time);
1063         pObject->pszValue[0] = _convert_tm_to_vdata_str(&display_time);
1064         pObject->valueCount = 1;
1065
1066
1067         /* Insert Vobject read status to VMessage tree */
1068         INSERT_VMSG_OBJ;
1069
1070         pObject->property = VMSG_TYPE_STATUS;
1071
1072         if (pMsg->bRead)
1073                 pObject->pszValue[0] = strdup("READ");
1074         else
1075                 pObject->pszValue[0] = strdup("UNREAD");
1076
1077         pObject->valueCount = 1;
1078
1079
1080         /* Insert VBody  tree for message body; */
1081         pBody = (VTree*)calloc(1, sizeof(VTree));
1082         if ( !pBody )
1083                 goto __CATCH_FAIL__;
1084         pBody->treeType = VBODY;
1085         pBody->pTop = NULL;
1086         pBody->pCur = NULL;
1087         pBody->pNext = NULL;
1088         pCurrent->pNext = pBody;
1089         pCurrent = pBody;
1090
1091         if (strlen(pMsg->subject) > 0) {
1092                 /* Insert Subject object */
1093                 INSERT_VBODY_OBJ;
1094                 pObject->property = VMSG_TYPE_SUBJECT;
1095                 pObject->pszValue[0] = strdup(pMsg->subject);
1096                 pObject->valueCount = 1;
1097         }
1098         /* Insert VBody object */
1099         INSERT_VBODY_OBJ;
1100         pObject->property = VMSG_TYPE_BODY;
1101
1102         if (pMsg->msgType.mainType == MSG_MMS_TYPE) {
1103                 /* Insert VBody for mms raw data; */
1104                 char* pFileData = NULL;
1105                 unique_ptr<char*, void(*)(char**)> buf(&pFileData, unique_ptr_deleter);
1106                 MMS_DATA_S *pMmsData = NULL;
1107                 int fileSize = 0;
1108                 char* msgText = NULL;
1109 #if 0
1110                 char filePath[MSG_FILEPATH_LEN_MAX] = {0, };
1111                 if(pMsg->msgType.subType == MSG_NOTIFICATIONIND_MMS)
1112                         pFileData = MsgOpenAndReadMmsFile(pMsg->msgData, 0, -1, &fileSize);
1113                 else {
1114                         err = MsgStoGetMmsRawFilePath(pDbHandle, pMsg->msgId, filePath);
1115
1116                         if (err != MSG_SUCCESS)
1117                                 goto __CATCH_FAIL__;
1118
1119                         pFileData = MsgOpenAndReadMmsFile(filePath, 0, -1, &fileSize);
1120                 }
1121 #else
1122
1123                 if (pMsg->bTextSms == false) {
1124                         if (MsgOpenAndReadFile(pMsg->msgData, &pFileData, &fileSize) == false) {
1125                                 goto __CATCH_FAIL__;
1126                         }
1127                 } else {
1128                         fileSize = strlen(pMsg->msgData);
1129                         pFileData = (char *)calloc(1, fileSize+1);
1130                         if (!pFileData)
1131                                 goto __CATCH_FAIL__;
1132                         snprintf(pFileData, fileSize, "%s", pMsg->msgData);
1133                 }
1134
1135                 if (MsgDeserializeMmsData(pFileData, fileSize, &pMmsData) != 0) {
1136                         MSG_DEBUG("Fail to Deserialize Message Data");
1137                         MsgMmsRelease(&pMmsData);
1138                         goto __CATCH_FAIL__;
1139                 }
1140
1141                 int serializedDataSize = 0;
1142
1143                 if (pMmsData) {
1144                         MsgMmsSetMultipartListData(pMmsData); /* app file -> data */
1145                         serializedDataSize = MsgSerializeMms(pMmsData, &pFileData);
1146                 }
1147
1148                 if (pFileData) {
1149                         fileSize = serializedDataSize;
1150                 }
1151
1152                 MsgMmsRelease(&pMmsData);
1153
1154 #endif
1155                 MSG_DEBUG("FILE SIZE IS %d, %s", fileSize, pFileData);
1156                 msgText = (char *)calloc(1, fileSize);
1157                 if(pFileData && msgText)
1158                         memcpy(msgText, pFileData, fileSize);
1159
1160                 pObject->numOfBiData = fileSize;
1161                 pObject->pszValue[0] = msgText;
1162                 pObject->valueCount = 1;
1163
1164                 if (pFileData) {
1165                         free(pFileData);
1166                         pFileData = NULL;
1167                 }
1168         }
1169
1170         /* Insert parameter for base64 encoding */
1171         MSG_DEBUG("before to start INSERT_PARAM");
1172         INSERT_PARAM;
1173         pObject->pParam = param;
1174         param->parameter = VMSG_PARAM_ENCODING;
1175         param->paramValue = VMSG_ENC_PARAM_BASE64;
1176
1177         /* Add VCard tree for recipient address information. */
1178         for (int i = 0; i < pMsg->nAddressCnt; ++i) {
1179                 pCard = (VTree*)calloc(1, sizeof(VTree));
1180                 if ( !pCard )
1181                         goto __CATCH_FAIL__;
1182
1183                 pCard->treeType = VCARD;
1184                 pCard->pTop = NULL;
1185                 pCard->pCur = NULL;
1186                 pCard->pNext = NULL;
1187                 pCurrent->pNext = pCard;
1188                 pCurrent = pCard;
1189
1190                 INSERT_VCARD_OBJ;
1191                 pObject->property = VCARD_TYPE_TEL;
1192                 pObject->pszValue[0] = strdup(pMsg->addressList[i].addressVal);
1193                 pObject->valueCount = 1;
1194         }
1195         MSG_DEBUG("before to start vmsg_encode");
1196         encoded_data = vmsg_encode(pMessage);
1197
1198         vmsg_free_vtree_memory(pMessage);
1199         MSG_END();
1200         return encoded_data;
1201
1202 __CATCH_FAIL__ :
1203         vmsg_free_vtree_memory(pMessage);
1204
1205         return NULL;
1206 }
1207
1208 char *MsgVMessageEncodeSMS(MSG_MESSAGE_INFO_S *pMsg)
1209 {
1210         MSG_BEGIN();
1211
1212         char *buf = NULL;
1213         int buf_size = VMSG_INIT_LENGTH;
1214         int len = 0;
1215
1216         __msgsvc_vmsg_initial();
1217
1218         buf = (char *)calloc(1, buf_size);
1219
1220         len = __msgsvc_vmsg_append_start_vmsg_1_1(&buf, &buf_size, len);
1221         if (len < 0) {
1222                 free(buf);
1223                 return NULL;
1224         }
1225
1226         len = __msgsvc_vmsg_append_msg(pMsg, &buf, &buf_size, len);
1227         if (len < 0) {
1228                 free(buf);
1229                 return NULL;
1230         }
1231
1232         len = __msgsvc_vmsg_append_end_vmsg(&buf, &buf_size, len);
1233         if (len < 0) {
1234                 free(buf);
1235                 return NULL;
1236         }
1237
1238         len = __msgsvc_vmsg_add_folding(&buf, &buf_size, len);
1239         if (len < 0) {
1240                 free(buf);
1241                 return NULL;
1242         }
1243
1244         MSG_END();
1245         return buf;
1246 }
1247 bool __msgsvc_vmsg_convert_vdata_to_tm_str(const char* szText, struct tm * tm)
1248 {
1249         if (szText == NULL)
1250                 return false;
1251
1252         char delims[] = ",";
1253         gchar **token = NULL;
1254         struct tm tmTemp;
1255
1256         token = g_strsplit_set(szText, delims, -1);
1257         if (token && token[0]) {
1258                 g_strstrip(token[0]);
1259                 strptime(token[0], "%I:%M%p", tm);
1260         } else {
1261                 g_strfreev(token);
1262                 return false;
1263         }
1264
1265         if (token && token[1]) {
1266                 g_strstrip(token[1]);
1267                 strptime(token[1], "%Y %b %e", &tmTemp);
1268         } else {
1269                 g_strfreev(token);
1270                 return false;
1271         }
1272
1273         tm->tm_year = tmTemp.tm_year;
1274         tm->tm_mon = tmTemp.tm_mon;
1275         tm->tm_mday = tmTemp.tm_mday;
1276         tm->tm_sec = 0;
1277
1278         g_strfreev(token);
1279         return true;
1280 }
1281
1282
1283 static inline char* __msgsvc_vmsg_remove_empty_line(char *src)
1284 {
1285         while (*src) {
1286                 if ('\n' != *src && '\r' != *src)
1287                         break;
1288                 src++;
1289         }
1290         return src;
1291 }
1292
1293 static char* __msgsvc_vmsg_check_word(char *src, const char *word)
1294 {
1295         bool start = false;
1296
1297         MSG_ERR_RET_VM(NULL == src, NULL, "The src is NULL.");
1298
1299         src = __msgsvc_vmsg_remove_empty_line(src);
1300
1301         while (*src) {
1302                 switch (*src) {
1303                 case ' ':
1304                 case ':':
1305                 case ';':
1306                         src++;
1307                         break;
1308                 default:
1309                         start = true;
1310                         break;
1311                 }
1312                 if (start) break;
1313         }
1314
1315         while (*src == *word) {
1316                 src++;
1317                 word++;
1318
1319                 if ('\0' == *src || '\0' == *word)
1320                         break;
1321         }
1322
1323         if ('\0' == *word)
1324                 return src;
1325         else
1326                 return NULL;
1327 }
1328
1329 static inline int __msgsvc_vmsg_check_quoted(char *src, int max, int *quoted)
1330 {
1331         int ret;
1332         if (TRUE == *quoted)
1333                 return TRUE;
1334
1335         while (*src && max) {
1336                 if ('Q' == *src) {
1337                         ret = strncmp(src, "QUOTED-PRINTABLE", sizeof("QUOTED-PRINTABLE") - 1);
1338                         if (!ret) {
1339                                 *quoted = TRUE;
1340                                 return TRUE;
1341                         }
1342                 } else if (':' == *src) {
1343                         break;
1344                 }
1345                 src++;
1346                 max--;
1347         }
1348         return FALSE;
1349 }
1350
1351 static inline int __msgsvc_vmsg_remove_folding(char *folded_src)
1352 {
1353         char *result = folded_src;
1354
1355         MSG_ERR_RET_VM(NULL == folded_src, MSG_ERR_INVALID_PARAMETER, " Invalid Parameter : __msgsvc_vmsg_remove_folding");
1356
1357         while (*folded_src) {
1358                 if ('\r' == *folded_src && '\n' == *(folded_src+1) && ' ' == *(folded_src+2))
1359                         folded_src += 3;
1360                 else if ('\n' == *folded_src && ' ' == *(folded_src+1))
1361                         folded_src += 2;
1362
1363                 if ('\0' == *folded_src)
1364                         break;
1365
1366                 *result = *folded_src;
1367                 result++;
1368                 folded_src++;
1369         }
1370         *result = '\0';
1371         return MSG_SUCCESS;
1372 }
1373
1374 static inline int __msgsvc_vmsg_hex_to_dec(char hex)
1375 {
1376         switch (hex) {
1377         case '0' ... '9':
1378                 return hex - '0';
1379         case 'a' ... 'f':
1380                 return hex - 'a' + 10;
1381         case 'A' ... 'F':
1382                 return hex - 'A' + 10;
1383         default:
1384                 return -1;
1385         }
1386 }
1387 static inline int __msgsvc_vmsg_decode_quoted_val(char *val)
1388 {
1389         char *src, *dest;
1390         int pre;
1391
1392         src = strchr(val, ':');
1393         if (NULL == src)
1394                 src = val;
1395
1396         dest = src;
1397         while (*src) {
1398                 if ('=' == *src) {
1399                         pre = __msgsvc_vmsg_hex_to_dec(*(src+1));
1400                         if (0 <= pre) {
1401                                 *dest = (char)((pre << 4) + __msgsvc_vmsg_hex_to_dec(*(src+2)));
1402                                 dest++;
1403                                 src += 2;
1404                         } else {
1405                                 if ('\r' == *(src+1) && '\n' == *(src+2))
1406                                         src += 2;
1407                         }
1408                 } else {
1409                         *dest = *src;
1410                         dest++;
1411                 }
1412                 src++;
1413         }
1414
1415         *dest = '\0';
1416         return dest - val;
1417 }
1418
1419 static inline char* __msgsvc_vmsg_translate_charset(char *src, int len)
1420 {
1421         int ret;
1422         char *val = src;
1423
1424         while (*val) {
1425                 if ('C' == *val) {
1426                         ret = strncmp(val, "CHARSET", sizeof("CHARSET") - 1);
1427                         if (!ret) {
1428                                 val += sizeof("CHARSET");
1429                                 break;
1430                         }
1431                 }
1432                 else if (':' == *val) {
1433                         return NULL;
1434                 }
1435                 val++;
1436         }
1437
1438         if (*val) {
1439                 UChar *temp;
1440                 UConverter *conv;
1441                 UErrorCode err = U_ZERO_ERROR;
1442                 int dest_size = 0;
1443                 int temp_size = 0;
1444                 int src_len, i = 0;
1445                 char enc[32] = {0}, *dest;
1446
1447                 while (';' != *val && ':' != *val  && ',' != *val) {
1448                         enc[i++] = *val++;
1449                 }
1450                 enc[i] = '\0';
1451                 if (0 == strcasecmp("UTF-8", enc))
1452                         return NULL;
1453
1454                 while (':' != *val)
1455                         val++;
1456
1457                 src_len = len - (val - src);
1458
1459                 temp_size = (src_len+1) * sizeof(UChar);
1460                 temp = (UChar *)malloc(temp_size);
1461                 conv = ucnv_open(enc, &err);
1462                 MSG_WARN_M(U_FAILURE(err), "ucnv_open() Failed(%d), enc=%s", err, enc);
1463                 ucnv_toUChars(conv, temp, temp_size, val, src_len, &err);
1464                 MSG_WARN_M(U_FAILURE(err), "ucnv_toUChars() Failed(%d), enc=%s", err, enc);
1465                 ucnv_close(conv);
1466
1467                 dest_size = temp_size*2;
1468                 dest = (char *)malloc(dest_size);
1469                 conv = ucnv_open("UTF-8", &err);
1470                 MSG_WARN_M(U_FAILURE(err), "ucnv_open() Failed(%d), enc=%s", err, enc);
1471                 ucnv_fromUChars(conv, dest, dest_size, temp, u_strlen(temp), &err);
1472                 MSG_WARN_M(U_FAILURE(err), "ucnv_fromUChars() Failed(%d), enc=%s", err, enc);
1473                 ucnv_close(conv);
1474                 free(temp);
1475
1476                 return dest;
1477         }
1478         return NULL;
1479 }
1480
1481 static void __msgsvc_vmsg_get_prefix(char **prefix, char *src)
1482 {
1483         char *temp = strchr(src, ':');
1484         if (temp) {
1485                 long len = (long)temp - (long)src;
1486                 *prefix = (char *)calloc(len+1, sizeof(char));
1487                 snprintf(*prefix, len+1, "%s", src);
1488         }
1489         else {
1490                 *prefix = NULL;
1491         }
1492 }
1493
1494 static void __msgsvc_vmsg_remove_spec_out(char **prefix)
1495 {
1496         if (NULL == prefix)
1497                 return;
1498         char *p = *prefix;
1499         while (p && *p) {
1500                 if (*p == '(') {
1501                         *p = '\0';
1502                         return;
1503                 }
1504                 p++;
1505         }
1506 }
1507
1508 static char* __msgsvc_vmsg_get_val(int ver, char *src, char **prefix, char **dest)
1509 {
1510         int quoted;
1511         bool start = false;
1512         char *cursor;
1513
1514         MSG_ERR_RET_VM(NULL == src, NULL, "Invalid parameter : The src is NULL.");
1515         MSG_ERR_RET_VM(NULL == dest, NULL, "sInvalid parameter : The dest is NULL.");
1516
1517         while (*src) {
1518                 switch (*src) {
1519                 case '\n':
1520                         return NULL;
1521                 case '\r':
1522                 case ' ':
1523                         src++;
1524                         break;
1525                 default:
1526                         start = true;
1527                         break;
1528                 }
1529                 if (start) break;
1530         }
1531
1532         quoted = FALSE;
1533         cursor = src;
1534         if (MSGSVC_VMSG_VER_1_1 == ver) {
1535                 while (*cursor) {
1536                         if ('=' == *cursor && __msgsvc_vmsg_check_quoted(src, cursor - src, &quoted)) {
1537                                 if ('\r' == *(cursor+1) && '\n' == *(cursor+2))
1538                                         cursor += 2;
1539                         } else {
1540                                 if ('\r' == *cursor && '\n' == *(cursor+1) && ' ' != *(cursor+2))
1541                                         break;
1542                                 if ('\n' == *cursor && ' ' != *(cursor+1))
1543                                         break;
1544                         }
1545
1546                         cursor++;
1547                 }
1548         }
1549         else {
1550                 while (*cursor) {
1551                         if ('\r' == *cursor && '\n' == *(cursor+1) && ' ' != *(cursor+2))
1552                                 break;
1553
1554                         if ('\n' == *cursor && ' ' != *(cursor+1))
1555                                 break;
1556
1557                         cursor++;
1558                 }
1559         }
1560
1561         if (src == cursor) {
1562                 *dest = NULL;
1563                 return NULL;
1564         }
1565         else {
1566                 int len = 0;
1567                 char temp = *cursor;
1568                 char *new_dest;
1569
1570                 if (prefix)
1571                         __msgsvc_vmsg_get_prefix(prefix, src);
1572
1573                 __msgsvc_vmsg_remove_spec_out(prefix);
1574
1575                 *cursor = '\0';
1576                 *dest = strdup(src);
1577                 if (MSGSVC_VMSG_VER_1_1 != ver)
1578                         __msgsvc_vmsg_remove_folding(*dest);
1579
1580                 if (__msgsvc_vmsg_check_quoted(*dest, -1, &quoted))
1581                         len = __msgsvc_vmsg_decode_quoted_val(*dest);
1582                 if (0 == len)
1583                         len = strlen(*dest);
1584                 new_dest = __msgsvc_vmsg_translate_charset(*dest, len);
1585                 if (new_dest) {
1586                         free(*dest);
1587                         *dest = new_dest;
1588                 }
1589                 *cursor = temp;
1590                 return (cursor + 1);
1591         }
1592 }
1593
1594 static int  __msgsvc_vmsg_check_content_type(char **vcard)
1595 {
1596         int i;
1597         char *new_start;
1598         for (i = VMSG_VALUE_NONE+1; i < VMSG_MAXIMUM_VALUE; i++) {
1599                 new_start = __msgsvc_vmsg_check_word(*vcard, content_name[i]);
1600                 if (new_start && (':' == *new_start || ';' == *new_start))
1601                         break;
1602         }
1603
1604         if (VMSG_MAXIMUM_VALUE == i)
1605                 return VMSG_VALUE_NONE;
1606         else {
1607                 *vcard = new_start;
1608                 return i;
1609         }
1610 }
1611
1612 static inline bool __msgsvc_vmsg_check_base64_encoded(char *src)
1613 {
1614         int ret;
1615         char *tmp = src;
1616
1617         while (*tmp) {
1618                 if ('B' == *tmp) {
1619                         ret = strncmp(tmp, "BASE64", sizeof("BASE64") - 1);
1620                         if (!ret)
1621                                 return true;
1622                 } else if (':' == *tmp || '\r' == *tmp) {
1623                         break;
1624                 }
1625                 tmp++;
1626         }
1627         return false;
1628 }
1629
1630 static char* __msgsvc_vmsg_decode_base64_val(char *val)
1631 {
1632         gsize size = 0;
1633         guchar *decoded_str;
1634         char *src;
1635         char *dest = NULL;
1636
1637         src = strchr(val, ':');
1638         if (NULL == src)
1639                 src = val;
1640         else
1641                 src++;
1642
1643         decoded_str = g_base64_decode(src, &size);
1644
1645         dest = (char *)calloc((src-val)+size+1, sizeof(char));
1646         snprintf(dest, (src-val)+1, "%s", val);
1647         snprintf(dest+(src-val), size+1, "%s", decoded_str);
1648         g_free(decoded_str);
1649
1650         return dest;
1651 }
1652
1653 static inline char*  __msgsvc_vmsg_pass_unsupported(char *vmsg)
1654 {
1655         while (*vmsg) {
1656                 if ('\n' == *vmsg)
1657                         return (vmsg + 1);
1658                 vmsg++;
1659         }
1660
1661         return NULL;
1662 }
1663
1664 static inline char* __msgsvc_vmsg_get_content_value(char *val)
1665 {
1666         char *temp;
1667
1668         temp = strchr(val, ':');
1669         if (temp)
1670                 temp++;
1671         else
1672                 temp = val;
1673
1674         MSG_ERR_RET_VM('\0' == *(temp) || '\r' == *(temp) || '\n' == *(temp),
1675                 NULL, "Invalid vcard content");
1676
1677         return temp;
1678 }
1679
1680 static char* __msgsvc_vmsg_remove_escape_char(char *str)
1681 {
1682         const char *s = SAFE_STR(str);
1683         char *r = (char *)s;
1684         while (*s) {
1685                 if (*s == '\\' && *(s+1)) {
1686                         char *n = (char*)(s+1);
1687                         switch (*n) {
1688                         case 'n':
1689                         case 'N':
1690                                 *r = '\n';
1691                                 s++;
1692                                 break;
1693                         case ';':
1694                         case ':':
1695                         case ',':
1696                         case '<':
1697                         case '>':
1698                         case '\\':
1699                                 *r = *n;
1700                                 s++;
1701                                 break;
1702                         case 0xA1: /* en/em backslash */
1703                                 if (*(n+1) && 0xAC == *(n+1)) {
1704                                         *r = *n;
1705                                         r++;
1706                                         *r = *(n+1);
1707                                         s+=2;
1708                                 }
1709                                 break;
1710                         case 0x81:  /* en/em backslash */
1711                                 if (*(n+1) && 0x5F == *(n+1)) {
1712                                         *r = *n;
1713                                         r++;
1714                                         *r = *(n+1);
1715                                         s+=2;
1716                                 }
1717                                 break;
1718                         default:
1719                                 *r = *s;
1720                                 break;
1721                         }
1722                         r++;
1723                         s++;
1724                 } else {
1725                         *r = *s;
1726                         r++;
1727                         s++;
1728                 }
1729         }
1730         *r = '\0';
1731         return str;
1732 }
1733
1734 static inline msg_error_t __msgsvc_vmsg_get_read_status(MSG_MESSAGE_INFO_S *pMsg, char *val)
1735 {
1736         char *temp;
1737
1738         temp = __msgsvc_vmsg_get_content_value(val);
1739         MSG_ERR_RET_VM(NULL == temp, MSG_ERR_INVALID_PARAMETER, "Invalid parameter : read status");
1740
1741         temp = __msgsvc_vmsg_remove_escape_char(temp);
1742
1743         if (strcmp(temp, content_name[VMSG_INDICATION_READ_STATUS_READ]) == 0)
1744                 pMsg->bRead = true;
1745         else if (strcmp(temp, content_name[VMSG_INDICATION_READ_STATUS_UNREAD]) == 0)
1746                 pMsg->bRead = false;
1747         else
1748                 return MSG_ERR_INVALID_PARAMETER;
1749
1750         MSG_DEBUG("pMsg->bRead = %d", pMsg->bRead);
1751         return MSG_SUCCESS;
1752 }
1753
1754 static inline msg_error_t __msgsvc_vmsg_get_msg_box(MSG_MESSAGE_INFO_S *pMsg, char *val)
1755 {
1756         char *temp;
1757
1758         temp = __msgsvc_vmsg_get_content_value(val);
1759         MSG_ERR_RET_VM(NULL == temp, MSG_ERR_INVALID_PARAMETER, "Invalid parameter : msg box");
1760
1761         temp = __msgsvc_vmsg_remove_escape_char(temp);
1762
1763         if (strcmp(temp, content_name[VMSG_INDICATION_MSG_BOX_DRAFT]) == 0) {
1764                 pMsg->folderId = MSG_DRAFT_ID;
1765                 pMsg->direction = MSG_DIRECTION_TYPE_MO;
1766                 pMsg->networkStatus = MSG_NETWORK_NOT_SEND;
1767         }
1768         else if (strcmp(temp, content_name[VMSG_INDICATION_MSG_BOX_INBOX]) == 0) {
1769                 pMsg->folderId = MSG_INBOX_ID;
1770                 pMsg->direction = MSG_DIRECTION_TYPE_MT;
1771                 pMsg->networkStatus = MSG_NETWORK_RECEIVED;
1772         } else if (strcmp(temp, content_name[VMSG_INDICATION_MSG_BOX_SENT]) == 0) {
1773                 pMsg->folderId = MSG_SENTBOX_ID;
1774                 pMsg->direction = MSG_DIRECTION_TYPE_MO;
1775                 pMsg->networkStatus = MSG_NETWORK_SEND_SUCCESS;
1776         } else
1777                 return MSG_ERR_INVALID_PARAMETER;
1778
1779         MSG_DEBUG("pMsg->folderId = %d", pMsg->folderId);
1780         return MSG_SUCCESS;
1781 }
1782
1783 static inline msg_error_t __msgsvc_vmsg_get_msg_type(MSG_MESSAGE_INFO_S *pMsg, char *val)
1784 {
1785         char *temp;
1786
1787         temp = __msgsvc_vmsg_get_content_value(val);
1788         MSG_ERR_RET_VM(NULL == temp, MSG_ERR_INVALID_PARAMETER, "Invalid parameter : msg type");
1789
1790         temp = __msgsvc_vmsg_remove_escape_char(temp);
1791
1792         if (strcmp(temp, content_name[VMSG_INDICATION_MESSAGE_TYPE_MSG]) == 0) {
1793                 pMsg->msgType.mainType = MSG_SMS_TYPE;
1794                 pMsg->msgType.subType = MSG_NORMAL_SMS;
1795                 pMsg->msgType.classType = MSG_CLASS_NONE;
1796         }
1797         else if (strcmp(temp, content_name[VMSG_INDICATION_MESSAGE_TYPE_INET]) == 0) {
1798                 /* To do */
1799         }
1800         else
1801                 return MSG_ERR_INVALID_PARAMETER;
1802
1803         MSG_DEBUG("pMsg->msgType.subType = %d", pMsg->msgType.subType);
1804         return MSG_SUCCESS;
1805 }
1806
1807 static inline msg_error_t __msgsvc_vmsg_get_address(MSG_MESSAGE_INFO_S *pMsg, char *prefix, char *val, int* vCardCnt)
1808 {
1809         char *temp;
1810         MSG_DEBUG("vCardCnt is : %d", *vCardCnt);
1811         if ((pMsg->folderId == MSG_SENTBOX_ID || pMsg->folderId == MSG_DRAFT_ID) && *vCardCnt == 1)
1812                 return MSG_SUCCESS;
1813
1814         if (pMsg->folderId == MSG_INBOX_ID && *vCardCnt > 1)
1815                 return MSG_SUCCESS;
1816
1817         temp = __msgsvc_vmsg_get_content_value(val);
1818         MSG_ERR_RET_VM(NULL == temp, MSG_ERR_INVALID_PARAMETER, "Invalid parameter : address");
1819
1820         temp = __msgsvc_vmsg_remove_escape_char(temp);
1821         MSG_ADDRESS_INFO_S * addrInfo = NULL;
1822
1823         pMsg->nAddressCnt++;
1824         MSG_DEBUG("Address is : %s", temp);
1825         MSG_DEBUG("Address Cnt : %d", pMsg->nAddressCnt);
1826
1827
1828         if (pMsg->addressList == NULL) {
1829                 addrInfo = (MSG_ADDRESS_INFO_S *)calloc(1, sizeof(MSG_ADDRESS_INFO_S));
1830         } else {
1831                 addrInfo = (MSG_ADDRESS_INFO_S *)realloc(pMsg->addressList, pMsg->nAddressCnt * sizeof(MSG_ADDRESS_INFO_S));
1832         }
1833
1834         if (addrInfo == NULL) {
1835                 return MSG_ERR_INVALID_PARAMETER;
1836         }
1837         pMsg->addressList = addrInfo;
1838
1839         pMsg->addressList[pMsg->nAddressCnt-1].addressType = MSG_ADDRESS_TYPE_PLMN;
1840         pMsg->addressList[pMsg->nAddressCnt-1].recipientType = MSG_RECIPIENTS_TYPE_TO;
1841         strncpy(pMsg->addressList[pMsg->nAddressCnt-1].addressVal, temp, MAX_ADDRESS_VAL_LEN);
1842         MSG_DEBUG("pMsg->addressList[pMsg->nAddressCnt-1].addressVal = %s", pMsg->addressList[pMsg->nAddressCnt-1].addressVal);
1843         return MSG_SUCCESS;
1844 }
1845
1846 static inline msg_error_t __msgsvc_vmsg_get_msg_date(MSG_MESSAGE_INFO_S *pMsg, char *val)
1847 {
1848         char *temp;
1849
1850         temp = __msgsvc_vmsg_get_content_value(val);
1851         MSG_ERR_RET_VM(NULL == temp, MSG_ERR_INVALID_PARAMETER, "Invalid parameter : date");
1852
1853         temp = __msgsvc_vmsg_remove_escape_char(temp);
1854         MSG_DEBUG("pMsg->displayTime = %s", temp);
1855         struct tm displayTime;
1856         if ( __msgsvc_vmsg_convert_vdata_to_tm_str(temp, &displayTime))
1857                 pMsg->displayTime = mktime(&displayTime);
1858         else
1859                 pMsg->displayTime = time(NULL);
1860         return MSG_SUCCESS;
1861 }
1862
1863 static inline msg_error_t __msgsvc_vmsg_get_msg_subject(MSG_MESSAGE_INFO_S *pMsg, char *val)
1864 {
1865         char *temp;
1866
1867         temp = __msgsvc_vmsg_get_content_value(val);
1868         MSG_ERR_RET_VM(NULL == temp, MSG_ERR_INVALID_PARAMETER, "Invalid parameter : subject");
1869
1870         temp = __msgsvc_vmsg_remove_escape_char(temp);
1871
1872         if (temp && temp[0] != '\0')
1873                 strncpy(pMsg->subject, temp, MAX_SUBJECT_LEN);
1874         MSG_DEBUG("pMsg->subject = %s", pMsg->subject);
1875         return MSG_SUCCESS;
1876 }
1877
1878 static inline bool __msgsvc_vmsg_get_msg_begin(MSG_MESSAGE_INFO_S *pMsg, char *val, int *vCardCnt)
1879 {
1880         pMsg->encodeType = MSG_ENCODE_AUTO;
1881
1882         char *temp;
1883
1884         temp = __msgsvc_vmsg_get_content_value(val);
1885         MSG_ERR_RET_VM(NULL == temp, MSG_ERR_INVALID_PARAMETER, "Invalid parameter : body");
1886
1887         temp = __msgsvc_vmsg_remove_escape_char(temp);
1888
1889         if (temp && temp[0] != '\0' && strcmp(temp, "VCARD") == 0) {
1890                 (*vCardCnt)++;
1891                 return true;
1892         }
1893         return false;
1894 }
1895
1896 static inline bool __msgsvc_vmsg_get_msg_end(MSG_MESSAGE_INFO_S *pMsg, char *val)
1897 {
1898         pMsg->encodeType = MSG_ENCODE_AUTO;
1899
1900         char *temp;
1901
1902         temp = __msgsvc_vmsg_get_content_value(val);
1903         MSG_ERR_RET_VM(NULL == temp, MSG_ERR_INVALID_PARAMETER, "Invalid parameter : body");
1904
1905         temp = __msgsvc_vmsg_remove_escape_char(temp);
1906
1907         if (temp && temp[0] != '\0' && strcmp(temp, "VMSG") == 0) {
1908                 MSG_DEBUG("VMessage decoding completed");
1909                 return true;
1910         } else if (temp && temp[0] != '\0' && strcmp(temp, "VCARD") == 0) {
1911                 MSG_DEBUG("VMessage decoding completed");
1912                 return false;
1913         }
1914         return false;
1915 }
1916
1917 static inline msg_error_t __msgsvc_vmsg_get_msg(int ver, char *vmsg, MSG_MESSAGE_INFO_S  *record)
1918 {
1919         int type;
1920         char *cursor, *new_start, *val, *prefix;
1921
1922         MSG_MESSAGE_INFO_S *pMsg = record;
1923         int vCardCnt = 0;
1924         bool isDateAvailable = false;
1925         pMsg->msgId = 0;
1926         pMsg->threadId = 0;
1927         bool end = false;
1928
1929         cursor = vmsg;
1930         while (cursor) {
1931                 val = NULL;
1932                 prefix = NULL;
1933                 bool base64_encoded = false;
1934                 char *bodyStart = cursor;
1935                 type =  __msgsvc_vmsg_check_content_type(&cursor);
1936
1937                 if (VMSG_VALUE_NONE == type) {
1938                         if (isDateAvailable == true) {
1939                                 isDateAvailable = false;
1940                                 /* body decoding */
1941                                 MSG_DEBUG("Decoding body :");
1942                                 bodyStart = __msgsvc_vmsg_pass_unsupported(bodyStart);
1943                                 int i = 0;
1944                                 char tempMsgText[MAX_MSG_TEXT_LEN + 1] = {0, };
1945                                 while (bodyStart) {
1946                                         if (i >= MAX_MSG_TEXT_LEN)
1947                                                 break;
1948                                         if (*bodyStart == 'E' && *(bodyStart+1) == 'N' && *(bodyStart+2) == 'D' && *(bodyStart+3) == ':') {
1949                                                 i++;
1950                                                 break;
1951                                         }
1952                                         tempMsgText[i] = *bodyStart;
1953                                         bodyStart++;
1954                                         i++;
1955                                 }
1956                                 tempMsgText[i] = '\0';
1957                                 char * temp = __msgsvc_vmsg_remove_escape_char(tempMsgText);
1958                                 strcpy(pMsg->msgText, temp);
1959                                 MSG_DEBUG("pMsg->msgText : %s", pMsg->msgText);
1960                                 pMsg->dataSize = strlen(pMsg->msgText);
1961                                 pMsg->bTextSms = true;
1962                                 base64_encoded = __msgsvc_vmsg_check_base64_encoded(pMsg->msgText);
1963
1964                                 if (base64_encoded) {
1965                                         char * decodedText = NULL;
1966                                         decodedText = __msgsvc_vmsg_decode_base64_val(pMsg->msgText);
1967                                         if (decodedText) {
1968                                                 strncpy(pMsg->msgText, decodedText, MAX_MSG_TEXT_LEN);
1969                                                 pMsg->dataSize = strlen(pMsg->msgText);
1970                                                 free(decodedText);
1971                                         } else {
1972                                                 strcpy(pMsg->msgText, "");
1973                                                 pMsg->dataSize = 0;
1974                                         }
1975                                 }
1976                                 g_free(prefix);
1977                                 g_free(val);
1978                                 return MSG_SUCCESS;
1979                         } else {
1980                                 new_start =  __msgsvc_vmsg_pass_unsupported(cursor);
1981                                 if (new_start) {
1982                                         cursor = new_start;
1983                                         continue;
1984                                 }
1985                                 else
1986                                         break;
1987                         }
1988                 }
1989
1990                 base64_encoded = __msgsvc_vmsg_check_base64_encoded(cursor);
1991
1992                 new_start = __msgsvc_vmsg_get_val(ver, cursor, &prefix, &val);
1993
1994                 if (NULL == new_start) {
1995                         g_free(prefix);
1996                         g_free(val);
1997                         continue;
1998                 }
1999
2000                 if (NULL == val) {
2001                         cursor = new_start;
2002                         g_free(prefix);
2003                         g_free(val);
2004                         continue;
2005                 }
2006
2007                 if (base64_encoded) {
2008                         char *temp = __msgsvc_vmsg_decode_base64_val(val);
2009                         g_free(val);
2010                         val = temp;
2011                 }
2012                 switch (type) {
2013                 case VMSG_INDICATION_READ_STATUS:
2014                         __msgsvc_vmsg_get_read_status(pMsg, val);
2015                         break;
2016                 case VMSG_INDICATION_MSG_BOX:
2017                         __msgsvc_vmsg_get_msg_box(pMsg, val);
2018                         break;
2019                 case VMSG_INDICATION_MESSAGE_TYPE:
2020                         __msgsvc_vmsg_get_msg_type(pMsg, val);
2021                         break;
2022                 case VMSG_VCARD_TEL:
2023                         __msgsvc_vmsg_get_address(pMsg, prefix, val, &vCardCnt);
2024                         break;
2025                 case VMSG_BODY_PROPERTY_DATE:
2026                         isDateAvailable = true;
2027                         __msgsvc_vmsg_get_msg_date(pMsg, val);
2028                         break;
2029                 case VMSG_BODY_PROPERTY_SUBJECT:
2030                         __msgsvc_vmsg_get_msg_subject(pMsg, val);
2031                         break;
2032                 case VMSG_MSG_BEGIN:
2033                         end = __msgsvc_vmsg_get_msg_begin(pMsg, val, &vCardCnt);
2034                 case VMSG_MSG_END:
2035                         end = __msgsvc_vmsg_get_msg_end(pMsg, val);
2036                         if (end) {
2037                                 g_free(val);
2038                                 g_free(prefix);
2039                                 return MSG_SUCCESS;
2040                         } else
2041                                 break;
2042                 default:
2043                         MSG_ERR("Invalid parameter : __msgsvc_vmsg_check_content_type() Failed(%d)", type);
2044                         g_free(val);
2045                         g_free(prefix);
2046                         return MSG_ERR_INVALID_PARAMETER;
2047                 }
2048                 g_free(val);
2049                 g_free(prefix);
2050                 cursor = new_start;
2051         }
2052
2053         MSG_ERR("Invalid vmsg");
2054         return MSG_ERR_INVALID_PARAMETER;
2055 }
2056
2057 msg_error_t MsgVMessageDecodeSMS(const char *vmsg_stream, MSG_MESSAGE_INFO_S *pMsg)
2058 {
2059         MSG_BEGIN();
2060
2061         int ret, ver;
2062
2063         char *vmsg = (char *)vmsg_stream;
2064
2065         char *MMSsend, *MMSretrieve, *MMSnoti;
2066
2067         MSG_ERR_RET_VM(NULL == vmsg_stream, MSG_ERR_INVALID_PARAMETER, "Invalid Parameter : vmsg");
2068
2069         vmsg  = __msgsvc_vmsg_check_word(vmsg, "BEGIN:VMSG");
2070         MSG_ERR_RET_VM(NULL == vmsg, MSG_ERR_INVALID_PARAMETER, "Invalid parameter : The vmsg is invalid.");
2071
2072         /* check for mms() */
2073         MMSsend = vmsg;
2074         MMSretrieve = vmsg;
2075         MMSnoti = vmsg;
2076
2077         MMSsend = __msgsvc_vmsg_check_word(MMSsend, "X-MESSAGE-TYPE:MMS SEND");
2078         MSG_ERR_RET_VM(NULL != MMSsend, MSG_ERR_INVALID_MESSAGE, "Invalid parameter : The vmsg format is invalid.");
2079
2080         MMSretrieve = __msgsvc_vmsg_check_word(MMSretrieve, "X-MESSAGE-TYPE:MMS RETRIEVE");
2081         MSG_ERR_RET_VM(NULL != MMSretrieve, MSG_ERR_INVALID_MESSAGE, "Invalid parameter : The vmsg format is invalid.");
2082
2083         MMSnoti = __msgsvc_vmsg_check_word(MMSnoti, "X-MESSAGE-TYPE:MMS NOTIFICATION");
2084         MSG_ERR_RET_VM(NULL != MMSnoti, MSG_ERR_INVALID_MESSAGE, "Invalid parameter : The vmsg format is invalid.");
2085
2086         /* decode sms() */
2087         __msgsvc_vmsg_initial();
2088
2089         vmsg = __msgsvc_vmsg_check_word(vmsg, "VERSION:1.1");
2090         MSG_ERR_RET_VM(NULL == vmsg, MSG_ERR_INVALID_PARAMETER, "Invalid parameter : The vmsg format is invalid.");
2091
2092         ver = MSGSVC_VMSG_VER_1_1;
2093
2094         ret = __msgsvc_vmsg_get_msg(ver, vmsg, pMsg);
2095         if (MSG_SUCCESS!= ret) {
2096                 return ret;
2097         }
2098         MSG_END();
2099         return MSG_SUCCESS;
2100 }
2101
2102