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