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