alloc-dealloc mismatch fixed
[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                                 }
265                                 else {
266                                         *r = *s;
267                                 }
268                                 break;
269                         case '\n':
270                                 *r = '\\';
271                                 r++;
272                                 str_len++;
273                                 if (*buf_size < str_len+len+1) {
274                                         *buf_size = *buf_size * 2;
275                                         if (NULL == (tmp = (char *)realloc(*buf, *buf_size)))
276                                                 return -1;
277                                         else {
278                                                 int pos_temp = r-(*buf+len);
279                                                 *buf = tmp;
280                                                 r = (char *)(*buf+len+pos_temp);
281                                         }
282                                 }
283                                 *r = 'n';
284                                 break;
285                         case ';':
286                         case ':':
287                         case ',':
288                         case '<':
289                         case '>':
290                         case '\\':
291                                 *r = '\\';
292                                 r++;
293                                 str_len++;
294                                 if (*buf_size < str_len+len+1) {
295                                         *buf_size = *buf_size * 2;
296                                         if (NULL == (tmp = (char *)realloc(*buf, *buf_size)))
297                                                 return -1;
298                                         else {
299                                                 int pos_temp = r-(*buf+len);
300                                                 *buf = tmp;
301                                                 r = (char *)(*buf+len+pos_temp);
302                                         }
303                                 }
304                                 *r = *s;
305                                 break;
306                         case 0xA1:
307                                 if (*(s+1) && 0xAC == *(s+1)) { /* en/em backslash */
308                                         *r = '\\';
309                                         r++;
310                                         str_len++;
311                                         if (*buf_size < str_len+len+1) {
312                                                 *buf_size = *buf_size * 2;
313                                                 if (NULL == (tmp = (char *)realloc(*buf, *buf_size)))
314                                                         return -1;
315                                                 else {
316                                                         int pos_temp = r-(*buf+len);
317                                                         *buf = tmp;
318                                                         r = (char *)(*buf+len+pos_temp);
319                                                 }
320                                         }
321
322                                         *r = *s;
323                                         r++;
324                                         s++;
325                                         if (*buf_size < str_len+len+1) {
326                                                 *buf_size = *buf_size * 2;
327                                                 if (NULL == (tmp = (char *)realloc(*buf, *buf_size)))
328                                                         return -1;
329                                                 else {
330                                                         int pos_temp = r-(*buf+len);
331                                                         *buf = tmp;
332                                                         r = (char *)(*buf+len+pos_temp);
333                                                 }
334                                         }
335                                         *r = *s;
336                                 }
337                                 else {
338                                         *r = *s;
339                                 }
340                                 break;
341                         case 0x81:
342                                 if (*(s+1) && 0x5F == *(s+1)) { /* en/em backslash */
343                                         *r = '\\';
344                                         r++;
345                                         str_len++;
346                                         if (*buf_size < str_len+len+1) {
347                                                 *buf_size = *buf_size * 2;
348                                                 if (NULL == (tmp = (char *)realloc(*buf, *buf_size)))
349                                                         return -1;
350                                                 else {
351                                                         int pos_temp = r-(*buf+len);
352                                                         *buf = tmp;
353                                                         r = (char *)(*buf+len+pos_temp);
354                                                 }
355                                         }
356
357                                         *r = *s;
358                                         r++;
359                                         s++;
360                                         if (*buf_size < str_len+len+1) {
361                                                 *buf_size = *buf_size * 2;
362                                                 if (NULL == (tmp = (char *)realloc(*buf, *buf_size)))
363                                                         return -1;
364                                                 else {
365                                                         int pos_temp = r-(*buf+len);
366                                                         *buf = tmp;
367                                                         r = (char *)(*buf+len+pos_temp);
368                                                 }
369                                         }
370                                         *r = *s;
371                                 }
372                                 else {
373                                         *r = *s;
374                                 }
375                                 break;
376                         default:
377                                 *r = *s;
378                                 break;
379                         }
380                         r++;
381                         s++;
382                 }
383                 len_temp = str_len;
384         }
385         else {
386                 len_temp = snprintf(*buf+len, *buf_size-len+1, "%s", safe_str);
387         }
388         len += len_temp;
389         return len;
390 }
391
392
393 /*==================================================================================================
394                                      DEFINES
395 ==================================================================================================*/
396 #define INSERT_VMSG_OBJ pObject = (VObject*)calloc(1, sizeof(VObject)); \
397                                       if ( !pObject )\
398 {\
399    vmsg_free_vtree_memory(pMessage);\
400    return false;\
401 }\
402 if (pMessage->pTop == NULL)\
403 {\
404    pMessage->pTop = pObject;\
405 }\
406 else\
407 {\
408    pMessage->pCur->pSibling = pObject;\
409 }\
410 pMessage->pCur = pObject;
411
412
413 #define INSERT_VBODY_OBJ pObject = (VObject*)calloc(1, sizeof(VObject));        \
414                                       if ( !pObject )\
415 {\
416    vmsg_free_vtree_memory(pMessage);\
417    return false;\
418 }\
419 if (pBody->pTop == NULL)\
420 {\
421    pBody->pTop = pObject;\
422 }\
423 else\
424 {\
425    pBody->pCur->pSibling = pObject;\
426 }\
427 pBody->pCur = pObject;
428
429
430 #define INSERT_VCARD_OBJ pObject = (VObject*)calloc(1, sizeof(VObject));        \
431                                       if ( !pObject )\
432 {\
433    vmsg_free_vtree_memory(pMessage);\
434    return false;\
435 }\
436 if (pCard->pTop == NULL)\
437 {\
438    pCard->pTop = pObject;\
439 }\
440 else\
441 {\
442    pCard->pCur->pSibling = pObject;\
443 }\
444 pCard->pCur = pObject;
445
446
447 #define INSERT_PARAM  param = (VParam*)calloc(1, sizeof(VParam));\
448                              if (!param)\
449 {\
450    vmsg_free_vtree_memory(pMessage);\
451    if (pObject != NULL)\
452    {\
453       free(pObject);\
454       pObject = NULL;\
455    }\
456    return false;\
457 }
458
459
460 /*==================================================================================================
461                                      FUNCTION IMPLEMENTATION
462 ==================================================================================================*/
463
464 char* _convert_tm_to_vdata_str(const struct tm * tm)
465 {
466         char str[17] = {0, };
467
468         snprintf(str, 17, "%04d%02d%02dT%02d%02d%02dZ",
469                 tm->tm_year + 1900,
470                 tm->tm_mon +1,
471                 tm->tm_mday,
472                 tm->tm_hour,
473                 tm->tm_min,
474                 tm->tm_sec);
475
476         return strdup(str);
477 }
478
479 bool _convert_vdata_str_to_tm(const char* szText, struct tm * tm)
480 {
481    if (szText == NULL) return false;
482    if (strlen(szText) < 15) return false;
483    if (szText[8] != 'T') return false;
484
485    char szBuff[8]={0};
486    memset(tm, 0, sizeof(struct tm));
487
488    /* year, month, day */
489    memcpy(szBuff, &(szText[0]), 4);
490    szBuff[4] = '\0';
491    tm->tm_year = atol(szBuff) - 1900;
492    if ((tm->tm_year > 137) || (tm->tm_year < 0))
493       tm->tm_year = 0;
494
495    memcpy(szBuff, &(szText[4]), 2);
496    szBuff[2] = '\0';
497    tm->tm_mon = atol(szBuff)-1;
498    if ((tm->tm_mon > 11) || (tm->tm_mon < 0))
499       tm->tm_mon = 11;
500
501    memcpy(szBuff, &(szText[6]), 2);
502    szBuff[2] = '\0';
503    tm->tm_mday = atol(szBuff);
504    if ((tm->tm_mday > 31) || (tm->tm_mday < 1))
505       tm->tm_mday = 31;
506
507    /* hour, minute, second */
508    memcpy(szBuff, &(szText[9]), 2);
509    szBuff[2] = '\0';
510    tm->tm_hour = atol(szBuff);
511    if ((tm->tm_hour > 23) || (tm->tm_hour < 0))
512       tm->tm_hour = 23;
513
514    memcpy(szBuff, &(szText[11]), 2);
515    szBuff[2] = '\0';
516    tm->tm_min = atol(szBuff);
517    if ((tm->tm_min > 59) || (tm->tm_min < 0))
518       tm->tm_min = 59;
519
520    memcpy(szBuff, &(szText[13]), 2);
521    szBuff[2] = '\0';
522    tm->tm_sec = atol(szBuff);
523    if ((tm->tm_sec > 59) || (tm->tm_sec < 0))
524       tm->tm_sec = 59;
525
526    return true;
527 }
528
529 int msgsvc_check_utf8(char c)
530 {
531         if ((c & 0xff) < (128 & 0xff))
532                 return 1;
533         else if ((c & (char)0xe0) == (char)0xc0)
534                 return 2;
535         else if ((c & (char)0xf0) == (char)0xe0)
536                 return 3;
537         else if ((c & (char)0xf8) == (char)0xf0)
538                 return 4;
539         else if ((c & (char)0xfc) == (char)0xf8)
540                 return 5;
541         else if ((c & (char)0xfe) == (char)0xfc)
542                 return 6;
543         else
544                 return MSG_ERR_INVALID_PARAMETER;
545 }
546
547 char* __msgsvc_vmsg_convert_tm_to_vdata_str(struct tm * tm)
548 {
549         char str[22] = {0, };
550         char APM[3] = {0, };
551         char month[15] = {0, };
552         int mon = 0;
553         int hour = 0;
554         mon = tm->tm_mon + 1;
555
556         if (tm->tm_hour >= 12)
557                 strncpy(APM, "PM", 2);
558         else
559                 strncpy(APM, "AM", 2);
560
561         if (tm->tm_hour > 12)
562                 hour = tm->tm_hour - 12;
563         else
564                 hour = tm->tm_hour;
565
566         switch(mon) {
567                 case 1:
568                         strncpy(month, "Jan", 3);
569                         break;
570                 case 2:
571                         strncpy(month, "Feb", 3);
572                         break;
573                 case 3:
574                         strncpy(month, "Mar", 3);
575                         break;
576                 case 4:
577                         strncpy(month, "Apr", 3);
578                         break;
579                 case 5:
580                         strncpy(month, "May", 3);
581                         break;
582                 case 6:
583                         strncpy(month, "Jun", 3);
584                         break;
585                 case 7:
586                         strncpy(month, "Jul", 3);
587                         break;
588                 case 8:
589                         strncpy(month, "Aug", 3);
590                         break;
591                 case 9:
592                         strncpy(month, "Sep", 3);
593                         break;
594                 case 10:
595                         strncpy(month, "Oct", 3);
596                         break;
597                 case 11:
598                         strncpy(month, "Nov", 3);
599                         break;
600                 case 12:
601                         strncpy(month, "Dec", 3);
602                         break;
603                 default:
604                         MSG_DEBUG("invalid month number");
605                 break;
606         }
607
608         snprintf(str, 22, "%d:%02d%s, %04d %s %d",
609                 hour,
610                 tm->tm_min,
611                 APM,
612                 tm->tm_year + 1900,
613                 month,
614                 tm->tm_mday);
615
616         return strdup(str);
617 }
618 static inline int __msgsvc_vmsg_add_folding(char **buf, int *buf_size, int buf_len)
619 {
620         int char_len = 0;
621         char *buf_copy = NULL;
622         int len, result_len;
623         char *r;
624         const char *s;
625         bool content_start = false;
626         bool encode_64 = false;
627
628         buf_copy = (char *)calloc(1, *buf_size);
629
630         s = *buf;
631         r = buf_copy;
632         len = result_len = 0;
633
634         while (*s) {
635                 if (*buf_size < result_len + 5) {
636                         char *tmp = NULL;
637                         *buf_size = *buf_size + 1000;
638                         if (NULL == (tmp = (char *)realloc(buf_copy, *buf_size))) {
639                                 free(buf_copy);
640                                 return -1;
641                         }
642                         else {
643                                 buf_copy = tmp;
644                                 r = (buf_copy + result_len);
645                         }
646                 }
647
648                 if (false == content_start) {
649                         if (':' == *s)
650                                 content_start = true;
651                         else if (0 == strncmp(s, "ENCODING=BASE64", strlen("ENCODING=BASE64")))
652                                 encode_64 = true;
653                 }
654
655                 if ('\r' == *s)
656                         len--;
657                 else if ('\n' == *s) {
658                         len = -1;
659                         char_len = 0;
660                         content_start = false;
661                         encode_64 = false;
662                 }
663
664                 if (0 == char_len) {
665                         if (false == encode_64)
666                                 char_len = msgsvc_check_utf8(*s);
667
668                         if (MSGSVC_VMSG_FOLDING_LIMIT <= len + char_len) {
669                                 *r = '\r';
670                                 r++;
671                                 *r = '\n';
672                                 r++;
673                                 *r = ' ';
674                                 r++;
675                                 len = 1;
676                                 result_len += 3;
677                         }
678                 }
679
680                 if (char_len)
681                         char_len--;
682
683                 *r = *s;
684                 r++;
685                 s++;
686                 len++;
687                 result_len++;
688         }
689         *r = '\0';
690         free(*buf);
691         *buf = buf_copy;
692         return result_len;
693 }
694
695 static inline int __msgsvc_vmsg_append_start_vmsg_1_1(char **buf, int *buf_size, int len)
696 {
697         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[BEGIN_VMSG]);
698         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
699         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[VERSION_VMSG]);
700         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
701         return len;
702 }
703
704 static inline int __msgsvc_vmsg_append_end_vmsg(char **buf, int *buf_size, int len)
705 {
706         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[END_VMSG]);
707         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
708         return len;
709 }
710
711 static inline int __msgsvc_vmsg_append_read_status(MSG_MESSAGE_INFO_S *pMsg, char **buf, int *buf_size, int len)
712 {
713         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[VMSG_INDICATION_READ_STATUS]);
714         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[VMSG_DATA_SEPARATOR]);
715         if (pMsg->bRead) {
716                 MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[VMSG_INDICATION_READ_STATUS_READ]);
717                 MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
718         } else {
719                 MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[VMSG_INDICATION_READ_STATUS_UNREAD]);
720                 MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
721         }
722         return len;
723 }
724 static inline int __msgsvc_vmsg_append_box_type(MSG_MESSAGE_INFO_S *pMsg, char **buf, int *buf_size, int len)
725 {
726         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[VMSG_INDICATION_MSG_BOX]);
727         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[VMSG_DATA_SEPARATOR]);
728         switch(pMsg->folderId) {
729                 case MSG_INBOX_ID:
730                         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[VMSG_INDICATION_MSG_BOX_INBOX]);
731
732                         break;
733                 case MSG_SENTBOX_ID:
734                         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[VMSG_INDICATION_MSG_BOX_SENT]);
735
736                         break;
737                 case MSG_DRAFT_ID:
738                         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[VMSG_INDICATION_MSG_BOX_DRAFT]);
739                         break;
740                 default:
741                         /* Discard User Defined, outbox or Spam folder's messages. */
742                         MSG_DEBUG("Invalid or unhandled msg box");
743         }
744         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
745         return len;
746 }
747
748 static inline int __msgsvc_vmsg_append_msg_type(MSG_MESSAGE_INFO_S *pMsg, char **buf, int *buf_size, int len)
749 {
750         /* TO DO check with msg text contains Only PrintableAscii if true then else handle INET_TYPE */
751         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[VMSG_INDICATION_MESSAGE_TYPE]);
752         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[VMSG_DATA_SEPARATOR]);
753         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[VMSG_INDICATION_MESSAGE_TYPE_MSG]);
754         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
755         return len;
756 }
757
758 static inline int __msgsvc_vmsg_append_origin_address_vcard(MSG_MESSAGE_INFO_S *pMsg, char **buf, int *buf_size, int len)
759 {
760         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[BEGIN_VCARD]);
761         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
762         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, content_name[VERSION_VCARD]);
763         MSGSVC_VMSG_APPEND_STR(buf, buf_size, len, MSGSVC_CRLF);
764         char originAddress[MAX_ADDRESS_VAL_LEN + 1] = {0, };
765         bool isDisplayName = false;
766
767         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 = (char *)calloc(1, fileSize+1);
1132                         if (!pFileData)
1133                                 goto __CATCH_FAIL__;
1134                         snprintf(pFileData, fileSize, "%s", pMsg->msgData);
1135                 }
1136
1137                 if (MsgDeserializeMmsData(pFileData, fileSize, &pMmsData) != 0) {
1138                         MSG_DEBUG("Fail to Deserialize Message Data");
1139                         MsgMmsRelease(&pMmsData);
1140                         goto __CATCH_FAIL__;
1141                 }
1142
1143                 int serializedDataSize = 0;
1144
1145                 if (pMmsData) {
1146                         MsgMmsSetMultipartListData(pMmsData); /* app file -> data */
1147                         serializedDataSize = MsgSerializeMms(pMmsData, &pFileData);
1148                 }
1149
1150                 if (pFileData) {
1151                         fileSize = serializedDataSize;
1152                 }
1153
1154                 MsgMmsRelease(&pMmsData);
1155
1156 #endif
1157                 MSG_DEBUG("FILE SIZE IS %d, %s", fileSize, pFileData);
1158                 if (fileSize > 0) {
1159                         msgText = (char *)calloc(1, fileSize);
1160                         if(pFileData && msgText)
1161                                 memcpy(msgText, pFileData, fileSize);
1162                 }
1163                 pObject->numOfBiData = fileSize;
1164                 pObject->pszValue[0] = msgText;
1165                 pObject->valueCount = 1;
1166
1167                 if (pFileData) {
1168                         delete [] pFileData;
1169                         pFileData = NULL;
1170                 }
1171         }
1172
1173         /* Insert parameter for base64 encoding */
1174         MSG_DEBUG("before to start INSERT_PARAM");
1175         INSERT_PARAM;
1176         pObject->pParam = param;
1177         param->parameter = VMSG_PARAM_ENCODING;
1178         param->paramValue = VMSG_ENC_PARAM_BASE64;
1179
1180         /* Add VCard tree for recipient address information. */
1181         for (int i = 0; i < pMsg->nAddressCnt; ++i) {
1182                 pCard = (VTree*)calloc(1, sizeof(VTree));
1183                 if ( !pCard )
1184                         goto __CATCH_FAIL__;
1185
1186                 pCard->treeType = VCARD;
1187                 pCard->pTop = NULL;
1188                 pCard->pCur = NULL;
1189                 pCard->pNext = NULL;
1190                 pCurrent->pNext = pCard;
1191                 pCurrent = pCard;
1192
1193                 INSERT_VCARD_OBJ;
1194                 pObject->property = VCARD_TYPE_TEL;
1195                 pObject->pszValue[0] = strdup(pMsg->addressList[i].addressVal);
1196                 pObject->valueCount = 1;
1197         }
1198         MSG_DEBUG("before to start vmsg_encode");
1199         encoded_data = vmsg_encode(pMessage);
1200
1201         vmsg_free_vtree_memory(pMessage);
1202         MSG_END();
1203         return encoded_data;
1204
1205 __CATCH_FAIL__ :
1206         vmsg_free_vtree_memory(pMessage);
1207
1208         return NULL;
1209 }
1210
1211 char *MsgVMessageEncodeSMS(MSG_MESSAGE_INFO_S *pMsg)
1212 {
1213         MSG_BEGIN();
1214
1215         char *buf = NULL;
1216         int buf_size = VMSG_INIT_LENGTH;
1217         int len = 0;
1218
1219         __msgsvc_vmsg_initial();
1220
1221         buf = (char *)calloc(1, buf_size);
1222
1223         len = __msgsvc_vmsg_append_start_vmsg_1_1(&buf, &buf_size, len);
1224         if (len < 0) {
1225                 free(buf);
1226                 return NULL;
1227         }
1228
1229         len = __msgsvc_vmsg_append_msg(pMsg, &buf, &buf_size, len);
1230         if (len < 0) {
1231                 free(buf);
1232                 return NULL;
1233         }
1234
1235         len = __msgsvc_vmsg_append_end_vmsg(&buf, &buf_size, len);
1236         if (len < 0) {
1237                 free(buf);
1238                 return NULL;
1239         }
1240
1241         len = __msgsvc_vmsg_add_folding(&buf, &buf_size, len);
1242         if (len < 0) {
1243                 free(buf);
1244                 return NULL;
1245         }
1246
1247         MSG_END();
1248         return buf;
1249 }
1250 bool __msgsvc_vmsg_convert_vdata_to_tm_str(const char* szText, struct tm * tm)
1251 {
1252         if (szText == NULL)
1253                 return false;
1254
1255         char delims[] = ",";
1256         gchar **token = NULL;
1257         struct tm tmTemp;
1258
1259         token = g_strsplit_set(szText, delims, -1);
1260         if (token && token[0]) {
1261                 g_strstrip(token[0]);
1262                 strptime(token[0], "%I:%M%p", tm);
1263         } else {
1264                 g_strfreev(token);
1265                 return false;
1266         }
1267
1268         if (token && token[1]) {
1269                 g_strstrip(token[1]);
1270                 strptime(token[1], "%Y %b %e", &tmTemp);
1271         } else {
1272                 g_strfreev(token);
1273                 return false;
1274         }
1275
1276         tm->tm_year = tmTemp.tm_year;
1277         tm->tm_mon = tmTemp.tm_mon;
1278         tm->tm_mday = tmTemp.tm_mday;
1279         tm->tm_sec = 0;
1280
1281         g_strfreev(token);
1282         return true;
1283 }
1284
1285
1286 static inline char* __msgsvc_vmsg_remove_empty_line(char *src)
1287 {
1288         while (*src) {
1289                 if ('\n' != *src && '\r' != *src)
1290                         break;
1291                 src++;
1292         }
1293         return src;
1294 }
1295
1296 static char* __msgsvc_vmsg_check_word(char *src, const char *word)
1297 {
1298         bool start = false;
1299
1300         MSG_ERR_RET_VM(NULL == src, NULL, "The src is NULL.");
1301
1302         src = __msgsvc_vmsg_remove_empty_line(src);
1303
1304         while (*src) {
1305                 switch (*src) {
1306                 case ' ':
1307                 case ':':
1308                 case ';':
1309                         src++;
1310                         break;
1311                 default:
1312                         start = true;
1313                         break;
1314                 }
1315                 if (start) break;
1316         }
1317
1318         while (*src == *word) {
1319                 src++;
1320                 word++;
1321
1322                 if ('\0' == *src || '\0' == *word)
1323                         break;
1324         }
1325
1326         if ('\0' == *word)
1327                 return src;
1328         else
1329                 return NULL;
1330 }
1331
1332 static inline int __msgsvc_vmsg_check_quoted(char *src, int max, int *quoted)
1333 {
1334         int ret;
1335         if (TRUE == *quoted)
1336                 return TRUE;
1337
1338         while (*src && max) {
1339                 if ('Q' == *src) {
1340                         ret = strncmp(src, "QUOTED-PRINTABLE", sizeof("QUOTED-PRINTABLE") - 1);
1341                         if (!ret) {
1342                                 *quoted = TRUE;
1343                                 return TRUE;
1344                         }
1345                 } else if (':' == *src) {
1346                         break;
1347                 }
1348                 src++;
1349                 max--;
1350         }
1351         return FALSE;
1352 }
1353
1354 static inline int __msgsvc_vmsg_remove_folding(char *folded_src)
1355 {
1356         char *result = folded_src;
1357
1358         MSG_ERR_RET_VM(NULL == folded_src, MSG_ERR_INVALID_PARAMETER, " Invalid Parameter : __msgsvc_vmsg_remove_folding");
1359
1360         while (*folded_src) {
1361                 if ('\r' == *folded_src && '\n' == *(folded_src+1) && ' ' == *(folded_src+2))
1362                         folded_src += 3;
1363                 else if ('\n' == *folded_src && ' ' == *(folded_src+1))
1364                         folded_src += 2;
1365
1366                 if ('\0' == *folded_src)
1367                         break;
1368
1369                 *result = *folded_src;
1370                 result++;
1371                 folded_src++;
1372         }
1373         *result = '\0';
1374         return MSG_SUCCESS;
1375 }
1376
1377 static inline int __msgsvc_vmsg_hex_to_dec(char hex)
1378 {
1379         switch (hex) {
1380         case '0' ... '9':
1381                 return hex - '0';
1382         case 'a' ... 'f':
1383                 return hex - 'a' + 10;
1384         case 'A' ... 'F':
1385                 return hex - 'A' + 10;
1386         default:
1387                 return -1;
1388         }
1389 }
1390 static inline int __msgsvc_vmsg_decode_quoted_val(char *val)
1391 {
1392         char *src, *dest;
1393         int pre;
1394
1395         src = strchr(val, ':');
1396         if (NULL == src)
1397                 src = val;
1398
1399         dest = src;
1400         while (*src) {
1401                 if ('=' == *src) {
1402                         pre = __msgsvc_vmsg_hex_to_dec(*(src+1));
1403                         if (0 <= pre) {
1404                                 *dest = (char)((pre << 4) + __msgsvc_vmsg_hex_to_dec(*(src+2)));
1405                                 dest++;
1406                                 src += 2;
1407                         } else {
1408                                 if ('\r' == *(src+1) && '\n' == *(src+2))
1409                                         src += 2;
1410                         }
1411                 } else {
1412                         *dest = *src;
1413                         dest++;
1414                 }
1415                 src++;
1416         }
1417
1418         *dest = '\0';
1419         return dest - val;
1420 }
1421
1422 static inline char* __msgsvc_vmsg_translate_charset(char *src, int len)
1423 {
1424         int ret;
1425         char *val = src;
1426
1427         while (*val) {
1428                 if ('C' == *val) {
1429                         ret = strncmp(val, "CHARSET", sizeof("CHARSET") - 1);
1430                         if (!ret) {
1431                                 val += sizeof("CHARSET");
1432                                 break;
1433                         }
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                 snprintf(*prefix, len+1, "%s", src);
1491         }
1492         else {
1493                 *prefix = NULL;
1494         }
1495 }
1496
1497 static void __msgsvc_vmsg_remove_spec_out(char **prefix)
1498 {
1499         if (NULL == prefix)
1500                 return;
1501         char *p = *prefix;
1502         while (p && *p) {
1503                 if (*p == '(') {
1504                         *p = '\0';
1505                         return;
1506                 }
1507                 p++;
1508         }
1509 }
1510
1511 static char* __msgsvc_vmsg_get_val(int ver, char *src, char **prefix, char **dest)
1512 {
1513         int quoted;
1514         bool start = false;
1515         char *cursor;
1516
1517         MSG_ERR_RET_VM(NULL == src, NULL, "Invalid parameter : The src is NULL.");
1518         MSG_ERR_RET_VM(NULL == dest, NULL, "sInvalid parameter : The dest is NULL.");
1519
1520         while (*src) {
1521                 switch (*src) {
1522                 case '\n':
1523                         return NULL;
1524                 case '\r':
1525                 case ' ':
1526                         src++;
1527                         break;
1528                 default:
1529                         start = true;
1530                         break;
1531                 }
1532                 if (start) break;
1533         }
1534
1535         quoted = FALSE;
1536         cursor = src;
1537         if (MSGSVC_VMSG_VER_1_1 == ver) {
1538                 while (*cursor) {
1539                         if ('=' == *cursor && __msgsvc_vmsg_check_quoted(src, cursor - src, &quoted)) {
1540                                 if ('\r' == *(cursor+1) && '\n' == *(cursor+2))
1541                                         cursor += 2;
1542                         } else {
1543                                 if ('\r' == *cursor && '\n' == *(cursor+1) && ' ' != *(cursor+2))
1544                                         break;
1545                                 if ('\n' == *cursor && ' ' != *(cursor+1))
1546                                         break;
1547                         }
1548
1549                         cursor++;
1550                 }
1551         }
1552         else {
1553                 while (*cursor) {
1554                         if ('\r' == *cursor && '\n' == *(cursor+1) && ' ' != *(cursor+2))
1555                                 break;
1556
1557                         if ('\n' == *cursor && ' ' != *(cursor+1))
1558                                 break;
1559
1560                         cursor++;
1561                 }
1562         }
1563
1564         if (src == cursor) {
1565                 *dest = NULL;
1566                 return NULL;
1567         }
1568         else {
1569                 int len = 0;
1570                 char temp = *cursor;
1571                 char *new_dest;
1572
1573                 if (prefix)
1574                         __msgsvc_vmsg_get_prefix(prefix, src);
1575
1576                 __msgsvc_vmsg_remove_spec_out(prefix);
1577
1578                 *cursor = '\0';
1579                 *dest = strdup(src);
1580                 if (MSGSVC_VMSG_VER_1_1 != ver)
1581                         __msgsvc_vmsg_remove_folding(*dest);
1582
1583                 if (__msgsvc_vmsg_check_quoted(*dest, -1, &quoted))
1584                         len = __msgsvc_vmsg_decode_quoted_val(*dest);
1585                 if (0 == len)
1586                         len = strlen(*dest);
1587                 new_dest = __msgsvc_vmsg_translate_charset(*dest, len);
1588                 if (new_dest) {
1589                         free(*dest);
1590                         *dest = new_dest;
1591                 }
1592                 *cursor = temp;
1593                 return (cursor + 1);
1594         }
1595 }
1596
1597 static int  __msgsvc_vmsg_check_content_type(char **vcard)
1598 {
1599         int i;
1600         char *new_start;
1601         for (i = VMSG_VALUE_NONE+1; i < VMSG_MAXIMUM_VALUE; i++) {
1602                 new_start = __msgsvc_vmsg_check_word(*vcard, content_name[i]);
1603                 if (new_start && (':' == *new_start || ';' == *new_start))
1604                         break;
1605         }
1606
1607         if (VMSG_MAXIMUM_VALUE == i)
1608                 return VMSG_VALUE_NONE;
1609         else {
1610                 *vcard = new_start;
1611                 return i;
1612         }
1613 }
1614
1615 static inline bool __msgsvc_vmsg_check_base64_encoded(char *src)
1616 {
1617         int ret;
1618         char *tmp = src;
1619
1620         while (*tmp) {
1621                 if ('B' == *tmp) {
1622                         ret = strncmp(tmp, "BASE64", sizeof("BASE64") - 1);
1623                         if (!ret)
1624                                 return true;
1625                 } else if (':' == *tmp || '\r' == *tmp) {
1626                         break;
1627                 }
1628                 tmp++;
1629         }
1630         return false;
1631 }
1632
1633 static char* __msgsvc_vmsg_decode_base64_val(char *val)
1634 {
1635         gsize size = 0;
1636         guchar *decoded_str;
1637         char *src;
1638         char *dest = NULL;
1639
1640         src = strchr(val, ':');
1641         if (NULL == src)
1642                 src = val;
1643         else
1644                 src++;
1645
1646         decoded_str = g_base64_decode(src, &size);
1647
1648         dest = (char *)calloc((src-val)+size+1, sizeof(char));
1649         snprintf(dest, (src-val)+1, "%s", val);
1650         snprintf(dest+(src-val), size+1, "%s", decoded_str);
1651         g_free(decoded_str);
1652
1653         return dest;
1654 }
1655
1656 static inline char*  __msgsvc_vmsg_pass_unsupported(char *vmsg)
1657 {
1658         while (*vmsg) {
1659                 if ('\n' == *vmsg)
1660                         return (vmsg + 1);
1661                 vmsg++;
1662         }
1663
1664         return NULL;
1665 }
1666
1667 static inline char* __msgsvc_vmsg_get_content_value(char *val)
1668 {
1669         char *temp;
1670
1671         temp = strchr(val, ':');
1672         if (temp)
1673                 temp++;
1674         else
1675                 temp = val;
1676
1677         MSG_ERR_RET_VM('\0' == *(temp) || '\r' == *(temp) || '\n' == *(temp),
1678                 NULL, "Invalid vcard content");
1679
1680         return temp;
1681 }
1682
1683 static char* __msgsvc_vmsg_remove_escape_char(char *str)
1684 {
1685         const char *s = SAFE_STR(str);
1686         char *r = (char *)s;
1687         while (*s) {
1688                 if (*s == '\\' && *(s+1)) {
1689                         char *n = (char*)(s+1);
1690                         switch ((unsigned int)*n) {
1691                         case 'n':
1692                         case 'N':
1693                                 *r = '\n';
1694                                 s++;
1695                                 break;
1696                         case ';':
1697                         case ':':
1698                         case ',':
1699                         case '<':
1700                         case '>':
1701                         case '\\':
1702                                 *r = *n;
1703                                 s++;
1704                                 break;
1705                         case 0xA1: /* en/em backslash */
1706                                 if (*(n+1) && 0xAC == *(n+1)) {
1707                                         *r = *n;
1708                                         r++;
1709                                         *r = *(n+1);
1710                                         s+=2;
1711                                 }
1712                                 break;
1713                         case 0x81:  /* en/em backslash */
1714                                 if (*(n+1) && 0x5F == *(n+1)) {
1715                                         *r = *n;
1716                                         r++;
1717                                         *r = *(n+1);
1718                                         s+=2;
1719                                 }
1720                                 break;
1721                         default:
1722                                 *r = *s;
1723                                 break;
1724                         }
1725                         r++;
1726                         s++;
1727                 } else {
1728                         *r = *s;
1729                         r++;
1730                         s++;
1731                 }
1732         }
1733         *r = '\0';
1734         return str;
1735 }
1736
1737 static inline msg_error_t __msgsvc_vmsg_get_read_status(MSG_MESSAGE_INFO_S *pMsg, char *val)
1738 {
1739         char *temp;
1740
1741         temp = __msgsvc_vmsg_get_content_value(val);
1742         MSG_ERR_RET_VM(NULL == temp, MSG_ERR_INVALID_PARAMETER, "Invalid parameter : read status");
1743
1744         temp = __msgsvc_vmsg_remove_escape_char(temp);
1745
1746         if (strcmp(temp, content_name[VMSG_INDICATION_READ_STATUS_READ]) == 0)
1747                 pMsg->bRead = true;
1748         else if (strcmp(temp, content_name[VMSG_INDICATION_READ_STATUS_UNREAD]) == 0)
1749                 pMsg->bRead = false;
1750         else
1751                 return MSG_ERR_INVALID_PARAMETER;
1752
1753         MSG_DEBUG("pMsg->bRead = %d", pMsg->bRead);
1754         return MSG_SUCCESS;
1755 }
1756
1757 static inline msg_error_t __msgsvc_vmsg_get_msg_box(MSG_MESSAGE_INFO_S *pMsg, char *val)
1758 {
1759         char *temp;
1760
1761         temp = __msgsvc_vmsg_get_content_value(val);
1762         MSG_ERR_RET_VM(NULL == temp, MSG_ERR_INVALID_PARAMETER, "Invalid parameter : msg box");
1763
1764         temp = __msgsvc_vmsg_remove_escape_char(temp);
1765
1766         if (strcmp(temp, content_name[VMSG_INDICATION_MSG_BOX_DRAFT]) == 0) {
1767                 pMsg->folderId = MSG_DRAFT_ID;
1768                 pMsg->direction = MSG_DIRECTION_TYPE_MO;
1769                 pMsg->networkStatus = MSG_NETWORK_NOT_SEND;
1770         }
1771         else if (strcmp(temp, content_name[VMSG_INDICATION_MSG_BOX_INBOX]) == 0) {
1772                 pMsg->folderId = MSG_INBOX_ID;
1773                 pMsg->direction = MSG_DIRECTION_TYPE_MT;
1774                 pMsg->networkStatus = MSG_NETWORK_RECEIVED;
1775         } else if (strcmp(temp, content_name[VMSG_INDICATION_MSG_BOX_SENT]) == 0) {
1776                 pMsg->folderId = MSG_SENTBOX_ID;
1777                 pMsg->direction = MSG_DIRECTION_TYPE_MO;
1778                 pMsg->networkStatus = MSG_NETWORK_SEND_SUCCESS;
1779         } else
1780                 return MSG_ERR_INVALID_PARAMETER;
1781
1782         MSG_DEBUG("pMsg->folderId = %d", pMsg->folderId);
1783         return MSG_SUCCESS;
1784 }
1785
1786 static inline msg_error_t __msgsvc_vmsg_get_msg_type(MSG_MESSAGE_INFO_S *pMsg, char *val)
1787 {
1788         char *temp;
1789
1790         temp = __msgsvc_vmsg_get_content_value(val);
1791         MSG_ERR_RET_VM(NULL == temp, MSG_ERR_INVALID_PARAMETER, "Invalid parameter : msg type");
1792
1793         temp = __msgsvc_vmsg_remove_escape_char(temp);
1794
1795         if (strcmp(temp, content_name[VMSG_INDICATION_MESSAGE_TYPE_MSG]) == 0) {
1796                 pMsg->msgType.mainType = MSG_SMS_TYPE;
1797                 pMsg->msgType.subType = MSG_NORMAL_SMS;
1798                 pMsg->msgType.classType = MSG_CLASS_NONE;
1799         }
1800         else if (strcmp(temp, content_name[VMSG_INDICATION_MESSAGE_TYPE_INET]) == 0) {
1801                 /* To do */
1802         }
1803         else
1804                 return MSG_ERR_INVALID_PARAMETER;
1805
1806         MSG_DEBUG("pMsg->msgType.subType = %d", pMsg->msgType.subType);
1807         return MSG_SUCCESS;
1808 }
1809
1810 static inline msg_error_t __msgsvc_vmsg_get_address(MSG_MESSAGE_INFO_S *pMsg, char *prefix, char *val, int* vCardCnt)
1811 {
1812         char *temp;
1813         MSG_DEBUG("vCardCnt is : %d", *vCardCnt);
1814         if ((pMsg->folderId == MSG_SENTBOX_ID || pMsg->folderId == MSG_DRAFT_ID) && *vCardCnt == 1)
1815                 return MSG_SUCCESS;
1816
1817         if (pMsg->folderId == MSG_INBOX_ID && *vCardCnt > 1)
1818                 return MSG_SUCCESS;
1819
1820         temp = __msgsvc_vmsg_get_content_value(val);
1821         MSG_ERR_RET_VM(NULL == temp, MSG_ERR_INVALID_PARAMETER, "Invalid parameter : address");
1822
1823         temp = __msgsvc_vmsg_remove_escape_char(temp);
1824         MSG_ADDRESS_INFO_S * addrInfo = NULL;
1825
1826         pMsg->nAddressCnt++;
1827         MSG_DEBUG("Address is : %s", temp);
1828         MSG_DEBUG("Address Cnt : %d", pMsg->nAddressCnt);
1829
1830
1831         if (pMsg->addressList == NULL) {
1832                 addrInfo = (MSG_ADDRESS_INFO_S *)calloc(1, sizeof(MSG_ADDRESS_INFO_S));
1833         } else {
1834                 addrInfo = (MSG_ADDRESS_INFO_S *)realloc(pMsg->addressList, pMsg->nAddressCnt * sizeof(MSG_ADDRESS_INFO_S));
1835         }
1836
1837         if (addrInfo == NULL) {
1838                 return MSG_ERR_INVALID_PARAMETER;
1839         }
1840         pMsg->addressList = addrInfo;
1841
1842         pMsg->addressList[pMsg->nAddressCnt-1].addressType = MSG_ADDRESS_TYPE_PLMN;
1843         pMsg->addressList[pMsg->nAddressCnt-1].recipientType = MSG_RECIPIENTS_TYPE_TO;
1844         strncpy(pMsg->addressList[pMsg->nAddressCnt-1].addressVal, temp, MAX_ADDRESS_VAL_LEN);
1845         MSG_DEBUG("pMsg->addressList[pMsg->nAddressCnt-1].addressVal = %s", pMsg->addressList[pMsg->nAddressCnt-1].addressVal);
1846         return MSG_SUCCESS;
1847 }
1848
1849 static inline msg_error_t __msgsvc_vmsg_get_msg_date(MSG_MESSAGE_INFO_S *pMsg, char *val)
1850 {
1851         char *temp;
1852
1853         temp = __msgsvc_vmsg_get_content_value(val);
1854         MSG_ERR_RET_VM(NULL == temp, MSG_ERR_INVALID_PARAMETER, "Invalid parameter : date");
1855
1856         temp = __msgsvc_vmsg_remove_escape_char(temp);
1857         MSG_DEBUG("pMsg->displayTime = %s", temp);
1858         struct tm displayTime;
1859         if ( __msgsvc_vmsg_convert_vdata_to_tm_str(temp, &displayTime))
1860                 pMsg->displayTime = mktime(&displayTime);
1861         else
1862                 pMsg->displayTime = time(NULL);
1863         return MSG_SUCCESS;
1864 }
1865
1866 static inline msg_error_t __msgsvc_vmsg_get_msg_subject(MSG_MESSAGE_INFO_S *pMsg, char *val)
1867 {
1868         char *temp;
1869
1870         temp = __msgsvc_vmsg_get_content_value(val);
1871         MSG_ERR_RET_VM(NULL == temp, MSG_ERR_INVALID_PARAMETER, "Invalid parameter : subject");
1872
1873         temp = __msgsvc_vmsg_remove_escape_char(temp);
1874
1875         if (temp && temp[0] != '\0')
1876                 strncpy(pMsg->subject, temp, MAX_SUBJECT_LEN);
1877         MSG_DEBUG("pMsg->subject = %s", pMsg->subject);
1878         return MSG_SUCCESS;
1879 }
1880
1881 static inline bool __msgsvc_vmsg_get_msg_begin(MSG_MESSAGE_INFO_S *pMsg, char *val, int *vCardCnt)
1882 {
1883         pMsg->encodeType = MSG_ENCODE_AUTO;
1884
1885         char *temp;
1886
1887         temp = __msgsvc_vmsg_get_content_value(val);
1888         MSG_ERR_RET_VM(NULL == temp, MSG_ERR_INVALID_PARAMETER, "Invalid parameter : body");
1889
1890         temp = __msgsvc_vmsg_remove_escape_char(temp);
1891
1892         if (temp && temp[0] != '\0' && strcmp(temp, "VCARD") == 0) {
1893                 (*vCardCnt)++;
1894                 return true;
1895         }
1896         return false;
1897 }
1898
1899 static inline bool __msgsvc_vmsg_get_msg_end(MSG_MESSAGE_INFO_S *pMsg, char *val)
1900 {
1901         pMsg->encodeType = MSG_ENCODE_AUTO;
1902
1903         char *temp;
1904
1905         temp = __msgsvc_vmsg_get_content_value(val);
1906         MSG_ERR_RET_VM(NULL == temp, MSG_ERR_INVALID_PARAMETER, "Invalid parameter : body");
1907
1908         temp = __msgsvc_vmsg_remove_escape_char(temp);
1909
1910         if (temp && temp[0] != '\0' && strcmp(temp, "VMSG") == 0) {
1911                 MSG_DEBUG("VMessage decoding completed");
1912                 return true;
1913         } else if (temp && temp[0] != '\0' && strcmp(temp, "VCARD") == 0) {
1914                 MSG_DEBUG("VMessage decoding completed");
1915                 return false;
1916         }
1917         return false;
1918 }
1919
1920 static inline msg_error_t __msgsvc_vmsg_get_msg(int ver, char *vmsg, MSG_MESSAGE_INFO_S  *record)
1921 {
1922         int type;
1923         char *cursor, *new_start, *val, *prefix;
1924
1925         MSG_MESSAGE_INFO_S *pMsg = record;
1926         int vCardCnt = 0;
1927         bool isDateAvailable = false;
1928         pMsg->msgId = 0;
1929         pMsg->threadId = 0;
1930         bool end = false;
1931
1932         cursor = vmsg;
1933         while (cursor) {
1934                 val = NULL;
1935                 prefix = NULL;
1936                 bool base64_encoded = false;
1937                 char *bodyStart = cursor;
1938                 type =  __msgsvc_vmsg_check_content_type(&cursor);
1939
1940                 if (VMSG_VALUE_NONE == type) {
1941                         if (isDateAvailable == true) {
1942                                 isDateAvailable = false;
1943                                 /* body decoding */
1944                                 MSG_DEBUG("Decoding body :");
1945                                 bodyStart = __msgsvc_vmsg_pass_unsupported(bodyStart);
1946                                 int i = 0;
1947                                 char tempMsgText[MAX_MSG_TEXT_LEN + 1] = {0, };
1948                                 while (bodyStart) {
1949                                         if (i >= MAX_MSG_TEXT_LEN)
1950                                                 break;
1951                                         if (*bodyStart == 'E' && *(bodyStart+1) == 'N' && *(bodyStart+2) == 'D' && *(bodyStart+3) == ':') {
1952                                                 i++;
1953                                                 break;
1954                                         }
1955                                         tempMsgText[i] = *bodyStart;
1956                                         bodyStart++;
1957                                         i++;
1958                                 }
1959                                 tempMsgText[i] = '\0';
1960                                 char * temp = __msgsvc_vmsg_remove_escape_char(tempMsgText);
1961                                 snprintf(pMsg->msgText, sizeof(pMsg->msgText), "%s", temp);
1962                                 MSG_DEBUG("pMsg->msgText : %s", pMsg->msgText);
1963                                 pMsg->dataSize = strlen(pMsg->msgText);
1964                                 pMsg->bTextSms = true;
1965                                 base64_encoded = __msgsvc_vmsg_check_base64_encoded(pMsg->msgText);
1966
1967                                 if (base64_encoded) {
1968                                         char * decodedText = NULL;
1969                                         decodedText = __msgsvc_vmsg_decode_base64_val(pMsg->msgText);
1970                                         if (decodedText) {
1971                                                 strncpy(pMsg->msgText, decodedText, MAX_MSG_TEXT_LEN);
1972                                                 pMsg->dataSize = strlen(pMsg->msgText);
1973                                                 free(decodedText);
1974                                         } else {
1975                                                 pMsg->msgText[0] = '\0';
1976                                                 pMsg->dataSize = 0;
1977                                         }
1978                                 }
1979                                 g_free(prefix);
1980                                 g_free(val);
1981                                 return MSG_SUCCESS;
1982                         } else {
1983                                 new_start =  __msgsvc_vmsg_pass_unsupported(cursor);
1984                                 if (new_start) {
1985                                         cursor = new_start;
1986                                         continue;
1987                                 }
1988                                 else
1989                                         break;
1990                         }
1991                 }
1992
1993                 base64_encoded = __msgsvc_vmsg_check_base64_encoded(cursor);
1994
1995                 new_start = __msgsvc_vmsg_get_val(ver, cursor, &prefix, &val);
1996
1997                 if (NULL == new_start) {
1998                         g_free(prefix);
1999                         g_free(val);
2000                         continue;
2001                 }
2002
2003                 if (NULL == val) {
2004                         cursor = new_start;
2005                         g_free(prefix);
2006                         g_free(val);
2007                         continue;
2008                 }
2009
2010                 if (base64_encoded) {
2011                         char *temp = __msgsvc_vmsg_decode_base64_val(val);
2012                         g_free(val);
2013                         val = temp;
2014                 }
2015                 switch (type) {
2016                 case VMSG_INDICATION_READ_STATUS:
2017                         __msgsvc_vmsg_get_read_status(pMsg, val);
2018                         break;
2019                 case VMSG_INDICATION_MSG_BOX:
2020                         __msgsvc_vmsg_get_msg_box(pMsg, val);
2021                         break;
2022                 case VMSG_INDICATION_MESSAGE_TYPE:
2023                         __msgsvc_vmsg_get_msg_type(pMsg, val);
2024                         break;
2025                 case VMSG_VCARD_TEL:
2026                         __msgsvc_vmsg_get_address(pMsg, prefix, val, &vCardCnt);
2027                         break;
2028                 case VMSG_BODY_PROPERTY_DATE:
2029                         isDateAvailable = true;
2030                         __msgsvc_vmsg_get_msg_date(pMsg, val);
2031                         break;
2032                 case VMSG_BODY_PROPERTY_SUBJECT:
2033                         __msgsvc_vmsg_get_msg_subject(pMsg, val);
2034                         break;
2035                 case VMSG_MSG_BEGIN:
2036                         end = __msgsvc_vmsg_get_msg_begin(pMsg, val, &vCardCnt);
2037                         break;
2038                 case VMSG_MSG_END:
2039                         end = __msgsvc_vmsg_get_msg_end(pMsg, val);
2040                         if (end) {
2041                                 g_free(val);
2042                                 g_free(prefix);
2043                                 return MSG_SUCCESS;
2044                         } else
2045                                 break;
2046                 default:
2047                         MSG_ERR("Invalid parameter : __msgsvc_vmsg_check_content_type() Failed(%d)", type);
2048                         g_free(val);
2049                         g_free(prefix);
2050                         return MSG_ERR_INVALID_PARAMETER;
2051                 }
2052                 g_free(val);
2053                 g_free(prefix);
2054                 cursor = new_start;
2055         }
2056
2057         MSG_ERR("Invalid vmsg");
2058         return MSG_ERR_INVALID_PARAMETER;
2059 }
2060
2061 msg_error_t MsgVMessageDecodeSMS(const char *vmsg_stream, MSG_MESSAGE_INFO_S *pMsg)
2062 {
2063         MSG_BEGIN();
2064
2065         int ret, ver;
2066
2067         char *vmsg = (char *)vmsg_stream;
2068
2069         char *MMSsend, *MMSretrieve, *MMSnoti;
2070
2071         MSG_ERR_RET_VM(NULL == vmsg_stream, MSG_ERR_INVALID_PARAMETER, "Invalid Parameter : vmsg");
2072
2073         vmsg  = __msgsvc_vmsg_check_word(vmsg, "BEGIN:VMSG");
2074         MSG_ERR_RET_VM(NULL == vmsg, MSG_ERR_INVALID_PARAMETER, "Invalid parameter : The vmsg is invalid.");
2075
2076         /* check for mms() */
2077         MMSsend = vmsg;
2078         MMSretrieve = vmsg;
2079         MMSnoti = vmsg;
2080
2081         MMSsend = __msgsvc_vmsg_check_word(MMSsend, "X-MESSAGE-TYPE:MMS SEND");
2082         MSG_ERR_RET_VM(NULL != MMSsend, MSG_ERR_INVALID_MESSAGE, "Invalid parameter : The vmsg format is invalid.");
2083
2084         MMSretrieve = __msgsvc_vmsg_check_word(MMSretrieve, "X-MESSAGE-TYPE:MMS RETRIEVE");
2085         MSG_ERR_RET_VM(NULL != MMSretrieve, MSG_ERR_INVALID_MESSAGE, "Invalid parameter : The vmsg format is invalid.");
2086
2087         MMSnoti = __msgsvc_vmsg_check_word(MMSnoti, "X-MESSAGE-TYPE:MMS NOTIFICATION");
2088         MSG_ERR_RET_VM(NULL != MMSnoti, MSG_ERR_INVALID_MESSAGE, "Invalid parameter : The vmsg format is invalid.");
2089
2090         /* decode sms() */
2091         __msgsvc_vmsg_initial();
2092
2093         vmsg = __msgsvc_vmsg_check_word(vmsg, "VERSION:1.1");
2094         MSG_ERR_RET_VM(NULL == vmsg, MSG_ERR_INVALID_PARAMETER, "Invalid parameter : The vmsg format is invalid.");
2095
2096         ver = MSGSVC_VMSG_VER_1_1;
2097
2098         ret = __msgsvc_vmsg_get_msg(ver, vmsg, pMsg);
2099         if (MSG_SUCCESS!= ret) {
2100                 return ret;
2101         }
2102         MSG_END();
2103         return MSG_SUCCESS;
2104 }
2105
2106