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