Sync with tizen 2.4
[platform/core/messaging/msg-service.git] / plugin / mms_plugin / MmsPluginCodecCommon.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 <ctype.h>
18 #include "MmsPluginDebug.h"
19 #include "MmsPluginCodecCommon.h"
20 #include "MmsPluginMIME.h"
21 #include "MmsPluginUtil.h"
22 #include "MmsPluginTextConvert.h"
23
24 #include <string>
25 using namespace std;
26
27 #define MMS_MAX_FIELD_VALUE_COUNT       74
28 #define MMS_MAX_FIELD_TYPE_COUNT        21
29
30 typedef struct {
31         const char *szText;
32         UINT16 binary;
33 } MmsField;
34
35 /* Reference : MMS-209-Encapsulation & WAP-203-WSP-20000504.pdf Table 39 */
36 const MmsField gMmsField[MMS_MAX_FIELD_TYPE_COUNT][MMS_MAX_FIELD_VALUE_COUNT] =
37 {
38         /* MMS Specific (MsgMmsMsg.h / MsgMmsUA.h) -----------------------*/
39
40         /* MmsCodeFieldCode */
41         {
42                 {"Bcc", 0x01},                                                          //0
43                 {"Cc", 0x02},
44                 {"X-Mms-Content-Location", 0x03},
45                 {"Content-Type", 0x04},
46                 {"Date", 0x05},
47                 {"X-Mms-Delivery-Report", 0x06},
48                 {"X-Mms-Delivery-Time", 0x07},
49                 {"X-Mms-Expiry", 0x08},
50                 {"From", 0x09},
51                 {"X-Mms-Message-Class", 0x0A},
52                 {"Message-ID", 0x0B},                                           // 10
53                 {"X-Mms-Message-Type", 0x0C},
54                 {"X-Mms-MMS-Version", 0x0D},
55                 {"X-Mms-Message-Size", 0x0E},
56                 {"X-Mms-Priority", 0x0F},
57                 {"X-Mms-Read-Reply", 0x10},
58                 {"X-Mms-Report-Allowed", 0x11},
59                 {"X-Mms-Response-Status", 0x12},
60                 {"X-Mms-Retrieve-Status", 0x19},                        /* Add by MMSENC v1.1 */
61                 {"X-Mms-Response-Text", 0x13},
62                 {"X-Mms-Retrieve-Text", 0x1A},                          // 20   /* Add by MMSENC v1.1 */
63                 {"X-Mms-Sender-Visibility", 0x14},
64                 {"X-Mms-Status", 0x15},
65                 {"Subject", 0x16},
66                 {"To", 0x17},
67                 {"X-Mms-Transaction-ID", 0x18},
68
69                 /* Add by MMSENC v1.1 */
70                 {"X-Mms-Read-Status", 0x1B},
71                 {"X-Mms-Reply-Charging", 0x1C},
72                 {"X-Mms-Reply-Charging-Deadline", 0x1D},        // 30
73                 {"X-Mms-Reply-Charging-ID", 0x1E},
74                 {"X-Mms-Reply-Charging-Size", 0x1F},
75                 {"X-Mms-Previously-Sent-By", 0x20},
76                 {"X-Mms-Previously-Sent-Date", 0x21},
77         },
78
79         /* MmsCodeParameterCode ( By WSP Table 38. Wellknown parameter Assignments ) */
80         {
81                 {"Charset", 0x01},              // v1.1 base
82                 {"Name", 0x05},                 // v1.1 base. 0x17 at v1.4
83                 {"FileName", 0x06},             // v1.1 base. ox18 at v1.4
84                 {"Type", 0x09},                 // v1.2 base
85                 {"Start", 0x0A},                // v1.2 base. 0x19 at v1.4
86                 {"Start-Info", 0x0B},   // v1.2 base. 0x1A at v1.4
87                 {"boundary", 0xFF},             //laconic_javaParamFix
88                 {"report-type", 0xFF},        // only used as parameter of Content-Type: multipart/report; report-type=delivery-status;
89 #ifdef FEATURE_JAVA_MMS
90                 {"Application-ID", 0xFF},
91                 {"Reply-To-Application-ID", 0xFF},
92 #endif
93         },
94
95         /* MmsCodeMsgBodyHeaderCode ( By WSP Table 39. Header Field Name Assignments ) */
96         {
97                 {"Content-Transfer-Encoding", 0xFFFF},  // only text encoding, no binary number
98                 {"Content-Disposition", 0x2E},                  // v1.1 base. 0x45 at v1.4
99                 {"Content-ID", 0x40},                                   // v1.3 base
100                 {"Content-Location", 0x0E},                             // v1.3 base
101                 {"X-Oma-Drm-Separate-Delivery", 0xFF }, // DRM RO WAITING
102         },
103
104         /* MmsCodeMsgType */
105         {
106                 {"m-send-req", 0x00},
107                 {"m-send-conf", 0x01},
108                 {"m-notification-ind", 0x02},
109                 {"m-notifyresp-ind", 0x03},
110                 {"m-retrieve-conf", 0x04},
111                 {"m-acknowledge-ind", 0x05},
112                 {"m-delivery-ind", 0x06},
113
114                 /* Add by MMSENC v1.1 */
115                 {"m-read-rec-ind", 0x07},
116                 {"m-read-orig-ind", 0x08},
117                 {"m-forward-req", 0x09},
118                 {"m-forward-conf", 0x0A}
119         },
120
121         /* MmsCodeDeliveryReport */
122         {
123                 { "Yes", 0x00 }, { "No", 0x01 }
124         },
125
126         /* MmsCodeTimeType */
127         {
128                 { "relative", 0x01 }, { "absolute", 0x00 }
129         },
130
131         /* MmsCodeMsgClass */
132         {
133                 {"Personal", 0x00},
134                 {"Advertisement", 0x01},
135                 {"Informational", 0x02},
136                 {"Auto", 0x03}
137         },
138
139         /* MmsCodePriority */
140         {
141                 { "Low", 0x00 }, { "Normal", 0x01 }, { "High", 0x02 }
142         },
143
144         /* MmsCodeResponseStatus */
145         {
146                 {"Ok", 0x00},
147                 {"Error-unspecified", 0x01},
148                 {"Error-service-denied", 0x02},
149                 {"Error-message-format-corrupt", 0x03},
150                 {"Error-sending-address-unresolved", 0x04},
151                 {"Error-message-not-found", 0x05},
152                 {"Error-network-problem", 0x06},
153                 {"Error-content-not-accepted", 0x07},
154                 {"Error-unsupported-message", 0x08},
155
156                 {"Error-transient-failure", 0x40},
157                 {"Error-transient-sending-address-unresolved", 0x41},
158                 {"Error-transient-message-not-found", 0x42},
159                 {"Error-transient-network-problem", 0x43},
160
161                 {"Error-permanent-failure", 0x60},
162                 {"Error-permanent-service-denied", 0x61},
163                 {"Error-permanent-message-format-corrupt", 0x62},
164                 {"Error-permanent-sending-address-unresolved", 0x63},
165                 {"Error-permanent-message-not-found", 0x64},
166                 {"Error-permanent-content-not-accepted", 0x65},
167                 {"Error-permanent-reply-charging-limitations-not-met", 0x66},
168                 {"Error-permanent-reply-charging-request-not-accepted", 0x67},
169                 {"Error-permanent-reply-charging-forwarding-denied", 0x68},
170                 {"Error-permanent-reply-charging-not-supported", 0x69},
171         },
172
173         /* MmsCodeRetrieveStatus */
174         {
175                 {"Ok", 0x00},
176                 {"Error-transient-failure", 0x40},
177                 {"Error-transient-message-not-found", 0x41},
178                 {"Error-transient-network-problem", 0x42},
179
180                 {"Error-permanent-failure", 0x60},
181                 {"Error-permanent-service-denied", 0x61},
182                 {"Error-permanent-message-not-found", 0x62},
183                 {"Error-permanent-content-unsupported", 0x63},
184         },
185
186         /* MmsCodeReadReply */
187         {
188                 { "Yes", 0x00 }, { "No", 0x01 }
189         },
190
191         /* MmsCodeReportAllowed */
192         {
193                 { "Yes", 0x00 }, { "No", 0x01 }
194         },
195
196         /* MmsCodeSenderVisibility */
197         {
198                 { "Show", 0x01 }, { "Hide", 0x00 }
199         },
200
201         /* MmsCodeMsgStatus */
202         {
203                 {"Expired", 0x00},
204                 {"Retrieved", 0x01},
205                 {"Rejected", 0x02},
206                 {"Deferred", 0x03},
207                 {"Unrecognised", 0x04},
208
209                 /* Add by MMSENC v1.1 */
210                 {"Indeterminate ", 0x05},
211                 {"Forwarded", 0x06},
212
213                 /* Add by MMSENC v1.2 */
214                 {"Unreachable", 0x07 }
215
216         },
217
218         /* MmsCodeReadStatus */
219         {
220                 {"Read", 0x00}, {"Deleted", 0x01}
221         },
222
223         /* MmsCodeAddressType */
224         {
225                 {"present", 0x00}, {"insert", 0x01}
226         },
227
228
229         /* MSG Specific (MsgMIMEExtern.h) -----------------------*/
230
231         /* MmsCodeCharSet */
232         {
233                 {"US-ASCII", 0x03},
234                 {"UTF-16", 0x03F7},
235                 {"CSUNICODE", 0x03E8},
236                 {"UTF-8", 0x6A},
237                 {"ISO-2022-KR", 0x25},
238                 {"KS_C_5601-1987", 0x24},
239                 {"EUC-KR", 0x26},
240                 {"ISO-2022-JP", 0x27},
241                 {"ISO-2022-JP-2", 0x28},
242                 {"ISO_8859-1", 0x04},
243                 {"ISO_8859-2", 0x05},
244                 {"ISO-8859-3", 0x06},
245                 {"ISO-8859-4", 0x07},
246                 {"ISO-8859-5", 0x08},
247                 {"ISO-8859-6", 0x09},
248                 {"ISO-8859-7", 0x0a},
249                 {"ISO-8859-8", 0x0b},
250                 {"ISO-8859-9", 0x0c},
251                 {"ISO-8859-10", 0x0d},
252                 {"ISO-8859-15", 0x6F},
253                 {"SHIFT_JIS", 0x11},
254                 {"EUC-JP", 0x13},
255                 {"GB2312", 0x07E9},
256                 {"BIG5", 0x0d},
257                 {"WINDOWS-1251", 0x08CB},
258                 {"KOI8-R", 0x0824},
259                 {"KOI8-U", 0x0828},
260         },
261
262         /* MmsCodeReplyCharging, */
263         {
264                 { "Requested", 0x00 },
265                 { "Requested text only", 0x01 },
266                 { "Accepted", 0x02 },
267                 { "Accepted text only", 0x03 }
268         },
269
270
271 //      OMNA WSP Content Type Numbers
272 //      http://technical.openmobilealliance.org/tech/omna/omna-wsp-content-type.aspx
273         {
274         //NOT USED THIS TABLE
275         },
276
277         /* MmsCodeMsgDisposition : Wsp Header (By Wsp 8.4.2.53) */
278         {
279                 {"form-data", 0x00},
280                 {"attachment", 0x01},
281                 {"inline", 0x02}
282         },
283
284         /* Content-transfer-encoding : HTTP Header(Binary Value is not assigned) */
285         {
286                 {"7bit", 0x00},
287                 {"8bit", 0x00},
288                 {"binary", 0x00},
289                 {"base64", 0x00},
290                 {"quoted-printable", 0x00}
291         }
292 };
293
294 const char *MmsGetTextValue(MmsCode i, int j)
295 {
296         if (i == MmsCodeContentType) {
297                 //apply UtyMime
298                 return MimeGetMimeStringFromMimeInt(j);
299         }
300
301         return (const char *)gMmsField[i][j].szText;
302 }
303
304 const char *MmsGetTextValuebyField(int field, int value)
305 {
306         const char *szValue = NULL;
307
308         switch (field) {
309         case MMS_CODE_MSGTYPE:
310                 szValue = MmsGetTextValue(MmsCodeMsgType, value);
311                 break;
312
313         case MMS_CODE_MSGCLASS:
314                 szValue = MmsGetTextValue(MmsCodeMsgClass, value);
315                 break;
316
317         case MMS_CODE_PRIORITY:
318                 szValue = MmsGetTextValue(MmsCodePriority, value);
319                 break;
320
321         case MMS_CODE_SENDERVISIBILLITY:
322                 szValue = MmsGetTextValue(MmsCodeSenderVisibility, value);
323                 break;
324
325         case MMS_CODE_DELIVERYREPORT:
326                 szValue = MmsGetTextValue(MmsCodeDeliveryReport, value);
327                 break;
328
329         case MMS_CODE_READREPLY:
330                 szValue = MmsGetTextValue(MmsCodeReadReply, value);
331                 break;
332
333         case MMS_CODE_MSGSTATUS:
334                 szValue = MmsGetTextValue(MmsCodeMsgStatus, value);
335                 break;
336
337         case MMS_CODE_REPORTALLOWED:
338                 szValue = MmsGetTextValue(MmsCodeReportAllowed, value);
339                 break;
340
341         case MMS_CODE_RESPONSESTATUS:
342                 szValue = MmsGetTextValue(MmsCodeResponseStatus, value);
343                 break;
344
345         /* Add by MMSENC v1.1 */
346         case MMS_CODE_READSTATUS:
347                 szValue = MmsGetTextValue(MmsCodeReadStatus, value);
348                 break;
349
350         default:
351                 szValue = NULL;
352                 break;
353         }
354
355         return szValue;
356 }
357
358 UINT16 MmsGetBinaryValue(MmsCode i, int j)
359 {
360         if (i == MmsCodeContentType) {
361                 return MimeGetBinaryValueFromMimeInt((MimeType)j);
362         }
363
364         return gMmsField[i][j].binary;
365 }
366
367 int MmsGetBinaryType(MmsCode i, UINT16 value)
368 {
369
370         for (int j = 0; j < MMS_MAX_FIELD_VALUE_COUNT; j++) {
371                 if (gMmsField[i][j].binary == value) {
372                         MSG_DEBUG("code [%d], value [0x%02x], ret type [%d]", i, value, j);
373                         return j;
374                 }
375         }
376
377         MSG_DEBUG("code [%d], value [0x%02x], ret type [Unknown]", i, value);
378         return -1;
379 }
380
381 int MmsGetTextType(MmsCode i, char *pValue)
382 {
383         int j = 0;
384
385         if (i == MmsCodeContentType) {
386                 /*apply UtyMime */
387                 return MimeGetMimeIntFromMimeString( pValue );
388         }
389
390         for (j = 0; j < MMS_MAX_FIELD_VALUE_COUNT; j++) {
391                 if (gMmsField[i][j].szText != NULL) {
392                         if (strcasecmp( gMmsField[i][j].szText, pValue ) == 0) {
393                                 return j;
394                         }
395                 }
396         }
397
398         return -1;
399 }
400
401 const char *MmsGetTextByCode(MmsCode i, UINT16 code)
402 {
403         for (int j = 0; j < MMS_MAX_FIELD_VALUE_COUNT; j++) {
404                 if (gMmsField[i][j].binary == code) {
405                         return gMmsField[i][j].szText;
406                 }
407         }
408         return NULL;
409 }
410
411
412
413 /* ==================================================================
414  *      Decode/Encode inline base64 string
415  *
416  * base64 : 3*8bit -> 4*6bit & convert the value into A~Z, a~z, 0~9, +, or /
417  * pad(=) is needed when the end of the string is < 24bit.
418  *
419  *     Value Encoding  Value Encoding  Value Encoding  Value Encoding
420  *         0 A            17 R            34 i            51 z
421  *         1 B            18 S            35 j            52 '0'
422  *         2 C            19 T            36 k            53 1
423  *         3 D            20 U            37 l            54 2
424  *         4 E            21 V            38 m            55 3
425  *         5 F            22 W            39 n            56 4
426  *         6 G            23 X            40 o            57 5
427  *         7 H            24 Y            41 p            58 6
428  *         8 I            25 Z            42 q            59 7
429  *         9 J            26 a            43 r            60 8
430  *        10 K            27 b            44 s            61 9
431  *        11 L            28 c            45 t            62 +
432  *        12 M            29 d            46 u            63 /
433  *        13 N            30 e            47 v
434  *        14 O            31 f            48 w         (pad) =
435  *        15 P            32 g            49 x
436  *        16 Q            33 h            50 y
437  *
438  * (1) the final quantum = 24 bits : no "=" padding,
439  * (2) the final quantum = 8 bits : two "=" + two characters
440  * (3) the final quantum = 16 bits : one "=" + three characters
441  * ================================================================== */
442
443 void *MsgDecodeBase64(unsigned char *pSrc, unsigned long srcLen, unsigned long *len)
444 {
445         char c;
446         void *ret = NULL;
447         char *d = NULL;
448         short e = 0;
449
450         ret = malloc((size_t)(*len = 4 + ((srcLen * 3) / 4)));
451         d = (char *)ret;
452
453         if (ret == NULL) {
454                 MSG_DEBUG("_MsgDecodeBase64: ret malloc Fail \n");
455                 return NULL;
456         }
457
458         memset(ret, 0, (size_t)*len);
459         *len = 0;
460
461         while (srcLen-- > 0) {
462                 c = *pSrc++;
463
464                 /* Convert base64 character into original value */
465
466                 if (isupper(c))
467                         c -= 'A';
468                 else if (islower(c))
469                         c -= 'a' - 26;
470                 else if (isdigit(c))
471                         c -= '0' - 52;
472                 else if (c == '+')
473                         c = 62;
474                 else if (c == '/')
475                         c = 63;
476                 else if (c == '=') {
477                         switch (e++) {
478                         case 2:
479                                 if (*pSrc != '=') {
480                                         *len = d - (char *)ret;
481                                         return ret;
482                                 }
483                                 break;
484                         case 3:
485                                 e = 0;
486                                 break;
487                         default:
488                                 *len = d - (char *)ret;
489                                 return ret;
490                         }
491                         continue;
492                 } else
493                         continue;                                       // Actually, never get here
494
495                 /* Pad 4*6bit character into 3*8bit character */
496
497                 switch (e++) {
498                 case 0:
499                         *d = c << 2;                    // byte 1: high 6 bits
500                         break;
501
502                 case 1:
503                         *d++ |= c >> 4;                 // byte 1: low 2 bits
504                         *d = c << 4;                    // byte 2: high 4 bits
505                         break;
506
507                 case 2:
508                         *d++ |= c >> 2;                 // byte 2: low 4 bits
509                         *d = c << 6;                    // byte 3: high 2 bits
510                         break;
511
512                 case 3:
513                         *d++ |= c;                              // byte 3: low 6 bits
514                         e = 0;                                  // Calculate next unit.
515                         break;
516
517                 default:
518                         MSG_DEBUG("_MsgDecodeBase64: Unknown paremeter\n");
519                         break;
520                 }
521         }
522
523         *len = d - (char *)ret;                 // Calculate the size of decoded string.
524
525         return ret;
526 }
527
528
529
530 /* ==========================================
531  *      Decode/Encode inline base64 string
532  *
533  * quoted-printable := ([*(ptext / SPACE / TAB) ptext] ["="] CRLF)
534  *       ; Maximum line length of 76 characters excluding CRLF
535  *
536  * ptext := octet /<any ASCII character except "=", SPACE, or TAB>
537  *       ; characters not listed as "mail-safe" in Appendix B
538  *       ; are also not recommended.
539  *
540  * octet := "=" 2(DIGIT / "A" / "B" / "C" / "D" / "E" / "F")
541  *       ; octet must be used for characters > 127, =, SPACE, or TAB.
542  *
543  * ==========================================*/
544
545
546 unsigned char *MsgDecodeQuotePrintable(unsigned char *pSrc, unsigned long srcLen, unsigned long *len)
547 {
548         unsigned char *ret = NULL;
549         unsigned char *d = NULL;
550         unsigned char *s = NULL;                                        /* last non-blank */
551         unsigned char c;
552         unsigned char e;
553
554         d = s = ret = (unsigned char *)malloc((size_t)srcLen + 1);
555         if (ret == NULL) {
556                 MSG_DEBUG("_MsgDecodeQuotePrintable: ret malloc Fail \n");
557                 return NULL;
558         }
559
560         *len = 0;
561         pSrc[srcLen] = '\0';
562
563         while ((c = *pSrc++)!= '\0') {
564                 switch (c) {
565                 case '=':                                                       /* octet characters (> 127, =, SPACE, or TAB) */
566                         switch (c = *pSrc++) {
567                         case '\0':                                      /* end of string -> postpone to while */
568                                 break;
569
570                         case '\015':                            /* CRLF */
571                                 if (*pSrc == '\012')
572                                         pSrc++;
573                                 break;
574
575                         default:                                        /* two hexes */
576                                 if (!isxdigit(c)) {
577                                         *d = '\0';
578                                         *len = d - ret;
579                                         return ret;
580                                 }
581
582                                 if (isdigit(c))
583                                         e = c - '0';
584                                 else
585                                         e = c - (isupper(c) ? 'A' - 10 : 'a' - 10);
586
587                                 c = *pSrc++;
588                                 if (!isxdigit(c)) {
589                                         *d = '\0';
590                                         *len = d - ret;
591                                         return ret;
592                                 }
593
594                                 if (isdigit(c))
595                                         c -= '0';
596                                 else
597                                         c -= (isupper(c) ? 'A' - 10 : 'a' - 10);
598
599                                 *d++ = c + (e << 4);
600                                 s = d;
601                                 break;
602                         }
603                         break;
604
605                 case ' ':                                                       /* skip the blank */
606                         *d++ = c;
607                         break;
608
609                 case '\015':                                            /* Line Feedback : to last non-blank character */
610                         d = s;
611                         break;
612
613                 default:
614                         *d++ = c;                                               /* ASCII character */
615                         s = d;
616                         break;
617                 }
618         }
619
620         *d = '\0';
621         *len = d - ret;
622
623         return ret;
624 }
625
626
627 /* ========================================
628  * Decode/Encode inline base64 string
629  * Inline base64 has no "\r\n" in it,
630  * and has charset and encoding sign in it
631  * ======================================== */
632 bool MsgEncode2Base64(void *pSrc, unsigned long srcLen, unsigned long *len, unsigned char *ret)
633 {
634         unsigned char *d = NULL;
635         unsigned char *s = (unsigned char *)pSrc;
636         char *v = (char *)"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
637         unsigned long i = ((srcLen + 2) / 3) * 4;
638
639         i += 2 * ((i / 60) + 1);
640         *len = i;
641
642         if (ret == NULL) {
643                 MSG_DEBUG("_MsgEncode2Base64: ret Memory Alloc Fail \n");
644                 return false;
645         }
646         memset(ret, 0, i);
647
648         d = ret;
649
650         /* Convert 3*8bit into 4*6bit */
651         for (i = 0; srcLen > 0; s += 3) {
652                 *d++ = v[s[0] >> 2];                                                                                                                    // byte 1: high 6 bits of character-1
653                 *d++ = v[((s[0] << 4) + (--srcLen ? (s[1] >> 4) : 0)) & 0x3f];                                  // byte 2: low 2 bits of character-1 and high 4 bits of character-2
654                 *d++ = srcLen ? v[((s[1] << 2) + (--srcLen ? (s[2] >> 6) : 0)) & 0x3f] : '=';   // byte 3: low 4 bits of charcter-2 and high 2 bits of character-3
655                 *d++ = srcLen ? v[s[2] & 0x3f] : '=';                                                                                   // byte 4: low 6 bits of character-3
656
657                 if (srcLen)
658                         srcLen--;
659         }
660
661         *d = '\0';
662
663         if (((unsigned long)(d - ret)) != *len) {
664                 *len = d - ret;
665                 MSG_DEBUG("base64 encoding length = %d \n", *len);
666         }
667
668         return true;
669 }
670
671 int extract_encoded_word_param(char *encoded_word, char **charset,  char **encoding, char **encoded_text, unsigned int *encoded_word_size)
672 {
673         char *start_ptr = NULL;
674         char *end_ptr = NULL;
675         char *q1_ptr = NULL;
676         char *q2_ptr = NULL;
677
678         char *char_set = NULL;
679         char *l_encoded_text = NULL;
680
681         char l_encoding[2] = {0,};
682
683         if (encoded_word == NULL)
684                 goto __CATCH;
685
686         if ( 6 > strlen(encoded_word)) {
687                 goto __CATCH;
688         }
689
690         start_ptr = encoded_word;
691
692         if ( (encoded_word[0] == '=' && encoded_word[1] == '?') //"=?"
693                          && ((q1_ptr = strchr(start_ptr + 2, MSG_CH_QUESTION)) != NULL) // '?'
694                          && ((q2_ptr = strchr(q1_ptr + 1, MSG_CH_QUESTION))!= NULL)             // '?'
695                          && ((end_ptr = strstr(q2_ptr + 1, MSG_STR_DEC_END))!= NULL)) //"?="
696         {
697
698                 //extract character set
699                 if ( q1_ptr - (start_ptr + 2) > 0 ) {
700
701                         char_set = (char*)calloc(1, q1_ptr - (start_ptr + 2) + 1);
702
703                         strncpy(char_set, (char*)((start_ptr + 2)), q1_ptr - (start_ptr + 2));
704
705                         MSG_DEBUG("character set [%s][%d]", char_set, strlen(char_set));
706
707
708                 } else {
709                         MSG_DEBUG("character set is NULL");
710                         goto __CATCH;
711                 }
712
713                 //extract encode type
714                 if ((*(q2_ptr - 1) == MSG_CH_BASE64_UPPER) || (*(q2_ptr - 1) == MSG_CH_BASE64_LOWER)
715                                 || (*(q1_ptr + 1) == MSG_CH_BASE64_UPPER) || (*(q1_ptr + 1) == MSG_CH_BASE64_LOWER))
716                 {
717                         l_encoding[0] = MSG_CH_BASE64_UPPER;
718                 } else if ((*(q2_ptr-1) == MSG_CH_QPRINT_UPPER) || (*(q2_ptr-1) == MSG_CH_QPRINT_LOWER)
719                                 || (*(q1_ptr+1) == MSG_CH_QPRINT_UPPER) || (*(q1_ptr+1) == MSG_CH_QPRINT_LOWER))
720                 {
721                         //QPRINT
722                         l_encoding[0] = MSG_CH_QPRINT_UPPER;
723
724                 } else {
725                         MSG_DEBUG("unknown encoding");
726                         goto __CATCH;
727                 }
728
729                 //extract encoded text
730                 if (end_ptr - q2_ptr > 1) {
731                         l_encoded_text = (char*)calloc(1, end_ptr - q2_ptr);
732
733                         strncpy(l_encoded_text, (char*)(q2_ptr + 1), end_ptr - q2_ptr -1);
734
735                         MSG_DEBUG("encoded text [%s][%d]", l_encoded_text, strlen(l_encoded_text));
736                 } else {
737                         MSG_DEBUG("encoded text is NULL");
738                         goto __CATCH;
739                 }
740
741                 *charset = char_set;
742                 *encoding = g_strdup(l_encoding);
743                 *encoded_text = l_encoded_text;
744                 *encoded_word_size = end_ptr - start_ptr + 2;
745
746         } else {
747                 MSG_DEBUG("It is not encoded word type");
748                 return -1;
749         }
750
751         return 0;
752
753 __CATCH:
754         MSG_FREE(char_set);
755         MSG_FREE(l_encoded_text);
756         return -1;
757 }
758
759 char *MsgDecodeText(const char *pOri)
760 {
761         MSG_BEGIN();
762
763         char *pSrc = NULL;
764
765         char *encoded_word_start_ptr = NULL;
766         char *normal_word_start_ptr = NULL;
767
768         char *charset = NULL;
769         char *encoding = NULL;
770         char *encoded_text = NULL;
771         char *decoded_text = NULL;
772
773         char *return_string= NULL;
774         string result_string;
775
776         bool b_encoded_word = false;
777
778         unsigned int encoded_word_size = 0;
779         unsigned int total_len = 0;
780         unsigned int decoded_len = 0;
781
782         // copy original string
783         if (pOri == NULL || strlen(pOri) <= 0) {
784                 MSG_DEBUG("Invalid parameter : [%s]", pOri);
785                 return NULL;
786         }
787
788         pSrc = g_strdup(pOri);
789         total_len = strlen(pOri);
790
791         MSG_DEBUG("input text : [%s][%d]", pSrc, total_len);
792
793         normal_word_start_ptr = pSrc;
794
795         while (normal_word_start_ptr < pSrc + total_len) {
796
797                 encoded_word_start_ptr = strstr(normal_word_start_ptr, MSG_STR_DEC_START);
798
799                 b_encoded_word = false;
800
801                 //Find encoded word
802                 while (b_encoded_word == false && encoded_word_start_ptr != NULL ) {
803
804                         if (extract_encoded_word_param(encoded_word_start_ptr, &charset, &encoding, &encoded_text, &encoded_word_size) == 0) {
805
806                                 if (charset && encoding && encoded_text && encoded_word_size > 0) {
807                                         b_encoded_word = true;
808                                         MSG_DEBUG("charset [%s], encoding [%s], encoded_text [%s], encoded_word_size [%d]", charset, encoding, encoded_text, encoded_word_size);
809                                         break;
810                                 }
811
812                                 MSG_FREE(charset);
813                                 MSG_FREE(encoding);
814                                 MSG_FREE(encoded_text);
815                                 encoded_word_size = 0;
816                         }
817
818                         encoded_word_start_ptr = strstr(encoded_word_start_ptr+1, MSG_STR_DEC_START); //find next encoded_start_ptr
819
820                 } // end of while
821
822                 if (b_encoded_word) {
823
824                         //copy normal text
825                         if (encoded_word_start_ptr - normal_word_start_ptr > 0) {
826                                 result_string.append(normal_word_start_ptr, encoded_word_start_ptr - normal_word_start_ptr);
827                                 MSG_DEBUG("copy normal text : [%s]", result_string.c_str());
828                         }
829
830                         if (strcasecmp(encoding, "B") == 0) {
831
832                                 MSG_DEBUG("Base64 encoded text [%s][%d]", encoded_text, strlen(encoded_text));
833
834                                 decoded_text = (char *)MsgDecodeBase64((unsigned char *)encoded_text, strlen(encoded_text), (ULONG *)&decoded_len);
835
836                                 if (decoded_text && decoded_len > 0) {
837
838                                         char *result_text = NULL;
839                                         int result_text_len = 0;
840
841                                         MSG_DEBUG("Base64 decoded text [%s][%d], outlen [%d]", decoded_text, strlen(decoded_text), decoded_len);
842
843                                         if (MmsPluginTextConvert("UTF-8", charset, decoded_text, decoded_len, &result_text, &result_text_len) == false) {
844                                                 MSG_DEBUG("MmsPluginTextConvert Fail");
845                                         }
846
847                                         if(result_text) {
848                                                 MSG_DEBUG("Text convert result [%s][%d]", result_text, strlen(result_text));
849
850                                                 result_string.append(result_text, result_text_len);
851
852                                                 MSG_FREE(result_text);
853                                         }
854
855                                 } else {
856                                         MSG_DEBUG("Fail base64 decode");
857                                 }
858
859                                 MSG_FREE(decoded_text);
860
861                         } else if (strcasecmp(encoding, "Q") == 0) {
862
863                                 char *result_text = NULL;
864                                 int result_text_len = 0;
865
866                                 MSG_DEBUG("Qprint encoded text [%s][%d]", encoded_text, strlen(encoded_text));
867
868                                 decoded_text = (char *)MsgDecodeQuotePrintable((unsigned char *)encoded_text, strlen(encoded_text), (ULONG *)&decoded_len);
869
870                                 if (decoded_text && decoded_len > 0) {
871
872                                         MSG_DEBUG("Qprint decoded text [%s][%d], outlen [%d]", decoded_text, strlen(decoded_text), decoded_len);
873
874                                         if (MmsPluginTextConvert("UTF-8", charset, decoded_text, decoded_len, &result_text, &result_text_len) == false) {
875                                                 MSG_DEBUG("MmsPluginTextConvert Fail");
876                                         }
877
878                                         if(result_text) {
879                                                 MSG_DEBUG("Text convert result [%s][%d]", result_text, strlen(result_text));
880
881                                                 result_string.append(result_text, result_text_len);
882
883                                                 MSG_FREE(result_text);
884                                         }
885
886                                 } else {
887                                         MSG_DEBUG("Fail Qprint decode");
888                                 }
889
890                                 MSG_FREE(decoded_text);
891                         }
892
893                         normal_word_start_ptr = encoded_word_start_ptr+encoded_word_size; //next
894
895                         MSG_FREE(charset);
896                         MSG_FREE(encoding);
897                         MSG_FREE(encoded_text);
898                         encoded_word_size = 0;
899
900                 } else {
901                         //copy remain normal text
902
903                         MSG_DEBUG("last text : [%s]", normal_word_start_ptr);
904
905                         result_string.append(normal_word_start_ptr);
906
907                         break;
908                 }
909
910         } //end of while
911
912         if (result_string.length() > 0) {
913                 return_string = g_strdup(result_string.c_str());
914                 MSG_DEBUG("return string: [%s]", return_string);
915         }
916
917         MSG_FREE(pSrc);
918
919         MSG_END();
920         return return_string;
921 }
922
923 static char gszDebugStringBuf[50];
924
925 static char *MmsDebugPrintUnknownValue(int value)
926 {
927         snprintf(gszDebugStringBuf, sizeof(gszDebugStringBuf), "unknown value(%d)", value);
928         return gszDebugStringBuf;
929 }
930
931
932 const char *MmsDebugGetMimeType(MimeType mimeType)
933 {
934         switch (mimeType) {
935         case MIME_APPLICATION_XML:
936                 return "MIME_APPLICATION_XML";
937         case MIME_APPLICATION_WML_XML:
938                 return "MIME_APPLICATION_WML_XML";
939         case MIME_APPLICATION_XHTML_XML:
940                 return "MIME_APPLICATION_XHTML_XML";
941         case MIME_APPLICATION_JAVA_VM:
942                 return "MIME_APPLICATION_JAVA_VM";
943         case MIME_APPLICATION_SMIL:
944                 return "MIME_APPLICATION_SMIL";
945         case MIME_APPLICATION_JAVA_ARCHIVE:
946                 return "MIME_APPLICATION_JAVA_ARCHIVE";
947         case MIME_APPLICATION_JAVA:
948                 return "MIME_APPLICATION_JAVA";
949         case MIME_APPLICATION_OCTET_STREAM:
950                 return "MIME_APPLICATION_OCTET_STREAM";
951         case MIME_APPLICATION_STUDIOM:
952                 return "MIME_APPLICATION_STUDIOM";
953         case MIME_APPLICATION_FUNMEDIA:
954                 return "MIME_APPLICATION_FUNMEDIA";
955         case MIME_APPLICATION_MSWORD:
956                 return "MIME_APPLICATION_MSWORD";
957         case MIME_APPLICATION_PDF:
958                 return "MIME_APPLICATION_PDF";
959         case MIME_APPLICATION_ASTERIC:
960                 return "MIME_APPLICATION_ASTERIC";
961         case MIME_APPLICATION_VND_WAP_XHTMLXML:
962                 return "MIME_APPLICATION_VND_WAP_XHTMLXML";
963         case MIME_APPLICATION_VND_WAP_WMLC:
964                 return "MIME_APPLICATION_VND_WAP_WMLC";
965         case MIME_APPLICATION_VND_WAP_WMLSCRIPTC:
966                 return "MIME_APPLICATION_VND_WAP_WMLSCRIPTC";
967         case MIME_APPLICATION_VND_WAP_WTA_EVENTC:
968                 return "MIME_APPLICATION_VND_WAP_WTA_EVENTC";
969         case MIME_APPLICATION_VND_WAP_UAPROF:
970                 return "MIME_APPLICATION_VND_WAP_UAPROF";
971         case MIME_APPLICATION_VND_WAP_SIC:
972                 return "MIME_APPLICATION_VND_WAP_SIC";
973         case MIME_APPLICATION_VND_WAP_SLC:
974                 return "MIME_APPLICATION_VND_WAP_SLC";
975         case MIME_APPLICATION_VND_WAP_COC:
976                 return "MIME_APPLICATION_VND_WAP_COC";
977         case MIME_APPLICATION_VND_WAP_SIA:
978                 return "MIME_APPLICATION_VND_WAP_SIA";
979         case MIME_APPLICATION_VND_WAP_CONNECTIVITY_WBXML:
980                 return "MIME_APPLICATION_VND_WAP_CONNECTIVITY_WBXML";
981         case MIME_APPLICATION_VND_WAP_MULTIPART_FORM_DATA:
982                 return "MIME_APPLICATION_VND_WAP_MULTIPART_FORM_DATA";
983         case MIME_APPLICATION_VND_WAP_MULTIPART_BYTERANGES:
984                 return "MIME_APPLICATION_VND_WAP_MULTIPART_BYTERANGES";
985         case MIME_APPLICATION_VND_WAP_MULTIPART_MIXED:
986                 return "MIME_APPLICATION_VND_WAP_MULTIPART_MIXED";
987         case MIME_APPLICATION_VND_WAP_MULTIPART_RELATED:
988                 return "MIME_APPLICATION_VND_WAP_MULTIPART_RELATED";
989         case MIME_APPLICATION_VND_WAP_MULTIPART_ALTERNATIVE:
990                 return "MIME_APPLICATION_VND_WAP_MULTIPART_ALTERNATIVE";
991         case MIME_APPLICATION_VND_WAP_MULTIPART_ASTERIC:
992                 return "MIME_APPLICATION_VND_WAP_MULTIPART_ASTERIC";
993         case MIME_APPLICATION_VND_OMA_DD_XML:
994                 return "MIME_APPLICATION_VND_OMA_DD_XML";
995         case MIME_APPLICATION_VND_OMA_DRM_MESSAGE:
996                 return "MIME_APPLICATION_VND_OMA_DRM_MESSAGE";
997         case MIME_APPLICATION_VND_OMA_DRM_CONTENT:
998                 return "MIME_APPLICATION_VND_OMA_DRM_CONTENT";
999         case MIME_APPLICATION_VND_OMA_DRM_RIGHTS_XML:
1000                 return "MIME_APPLICATION_VND_OMA_DRM_RIGHTS_XML";
1001         case MIME_APPLICATION_VND_OMA_DRM_RIGHTS_WBXML:
1002                 return "MIME_APPLICATION_VND_OMA_DRM_RIGHTS_WBXML";
1003         case MIME_APPLICATION_VND_SMAF:
1004                 return "MIME_APPLICATION_VND_SMAF";
1005         case MIME_APPLICATION_VND_RN_REALMEDIA:
1006                 return "MIME_APPLICATION_VND_RN_REALMEDIA";
1007         case MIME_APPLICATION_VND_SUN_J2ME_JAVA_ARCHIVE:
1008                 return "MIME_APPLICATION_VND_SUN_J2ME_JAVA_ARCHIVE";
1009         case MIME_APPLICATION_VND_SAMSUNG_THEME:
1010                 return "MIME_APPLICATION_VND_SAMSUNG_THEME";
1011         case MIME_APPLICATION_VND_EXCEL:
1012                 return "MIME_APPLICATION_VND_EXCEL";
1013         case MIME_APPLICATION_X_HDMLC:
1014                 return "MIME_APPLICATION_X_HDMLC";
1015         case MIME_APPLICATION_X_X968_USERCERT:
1016                 return "MIME_APPLICATION_X_X968_USERCERT";
1017         case MIME_APPLICATION_X_WWW_FORM_URLENCODED:
1018                 return "MIME_APPLICATION_X_WWW_FORM_URLENCODED";
1019         case MIME_APPLICATION_X_SMAF:
1020                 return "MIME_APPLICATION_X_SMAF";
1021         case MIME_APPLICATION_X_FLASH:
1022                 return "MIME_APPLICATION_X_FLASH";
1023         case MIME_APPLICATION_X_EXCEL:
1024                 return "MIME_APPLICATION_X_EXCEL";
1025         case MIME_APPLICATION_X_POWERPOINT:
1026                 return "MIME_APPLICATION_X_POWERPOINT";
1027
1028         case MIME_AUDIO_BASIC:
1029                 return "MIME_AUDIO_BASIC";
1030         case MIME_AUDIO_MPEG:
1031                 return "MIME_AUDIO_MPEG";
1032         case MIME_AUDIO_MP3:
1033                 return "MIME_AUDIO_MP3";
1034         case MIME_AUDIO_MPG3:
1035                 return "MIME_AUDIO_MPG3";
1036         case MIME_AUDIO_MPEG3:
1037                 return "MIME_AUDIO_MPEG3";
1038         case MIME_AUDIO_MPG:
1039                 return "MIME_AUDIO_MPG";
1040         case MIME_AUDIO_AAC:
1041                 return "MIME_AUDIO_AAC";
1042         case MIME_AUDIO_G72:
1043                 return "MIME_AUDIO_G72";
1044         case MIME_AUDIO_AMR:
1045                 return "MIME_AUDIO_AMR";
1046         case MIME_AUDIO_AMR_WB:
1047                 return "MIME_AUDIO_AMR_WB";
1048         case MIME_AUDIO_MMF:
1049                 return "MIME_AUDIO_MMF";
1050         case MIME_AUDIO_SMAF:
1051                 return "MIME_AUDIO_SMAF";
1052         case MIME_AUDIO_IMELODY:
1053                 return "MIME_AUDIO_IMELODY";
1054         case MIME_AUDIO_MELODY:
1055                 return "MIME_AUDIO_MELODY";
1056         case MIME_AUDIO_MID:
1057                 return "MIME_AUDIO_MID";
1058         case MIME_AUDIO_MIDI:
1059                 return "MIME_AUDIO_MIDI";
1060         case MIME_AUDIO_X_MID:
1061                 return "MIME_AUDIO_X_MID";
1062         case MIME_AUDIO_SP_MIDI:
1063                 return "MIME_AUDIO_SP_MIDI";
1064         case MIME_AUDIO_WAVE:
1065                 return "MIME_AUDIO_WAVE";
1066         case MIME_AUDIO_3GPP:
1067                 return "MIME_AUDIO_3GPP";
1068         case MIME_AUDIO_MP4:
1069                 return "MIME_AUDIO_MP4";
1070         case MIME_AUDIO_MP4A_LATM:
1071                 return "MIME_AUDIO_MP4A_LATM";
1072         case MIME_AUDIO_VND_RN_REALAUDIO:
1073                 return "MIME_AUDIO_VND_RN_REALAUDIO";
1074         case MIME_AUDIO_X_MPEG:
1075                 return "MIME_AUDIO_X_MPEG";
1076         case MIME_AUDIO_X_MP3:
1077                 return "MIME_AUDIO_X_MP3";
1078         case MIME_AUDIO_X_MPEG3:
1079                 return "MIME_AUDIO_X_MPEG3";
1080         case MIME_AUDIO_X_MPG:
1081                 return "MIME_AUDIO_X_MPG";
1082         case MIME_AUDIO_X_AMR:
1083                 return "MIME_AUDIO_X_AMR";
1084         case MIME_AUDIO_X_MMF:
1085                 return "MIME_AUDIO_X_MMF";
1086         case MIME_AUDIO_X_SMAF:
1087                 return "MIME_AUDIO_X_SMAF";
1088         case MIME_AUDIO_X_IMELODY:
1089                 return "MIME_AUDIO_X_IMELODY";
1090         case MIME_AUDIO_X_MIDI:
1091                 return "MIME_AUDIO_X_MIDI";
1092         case MIME_AUDIO_X_MPEGAUDIO:
1093                 return "MIME_AUDIO_X_MPEGAUDIO";
1094         case MIME_AUDIO_X_PN_REALAUDIO:
1095                 return "MIME_AUDIO_X_PN_REALAUDIO";
1096         case MIME_AUDIO_X_PN_MULTIRATE_REALAUDIO:
1097                 return "MIME_AUDIO_X_PN_MULTIRATE_REALAUDIO";
1098         case MIME_AUDIO_X_PN_MULTIRATE_REALAUDIO_LIVE:
1099                 return "MIME_AUDIO_X_PN_MULTIRATE_REALAUDIO_LIVE";
1100         case MIME_AUDIO_X_WAV:
1101                 return "MIME_AUDIO_X_WAV";
1102
1103         case MIME_IMAGE_GIF:
1104                 return "MIME_IMAGE_GIF";
1105         case MIME_IMAGE_JPEG:
1106                 return "MIME_IMAGE_JPEG";
1107         case MIME_IMAGE_JPG:
1108                 return "MIME_IMAGE_JPG";
1109         case MIME_IMAGE_TIFF:
1110                 return "MIME_IMAGE_TIFF";
1111         case MIME_IMAGE_TIF:
1112                 return "MIME_IMAGE_TIF";
1113         case MIME_IMAGE_PNG:
1114                 return "MIME_IMAGE_PNG";
1115         case MIME_IMAGE_WBMP:
1116                 return "MIME_IMAGE_WBMP";
1117         case MIME_IMAGE_PJPEG:
1118                 return "MIME_IMAGE_PJPEG";
1119         case MIME_IMAGE_BMP:
1120                 return "MIME_IMAGE_BMP";
1121         case MIME_IMAGE_SVG:
1122                 return "MIME_IMAGE_SVG";
1123         case MIME_IMAGE_SVG1:
1124                 return "MIME_IMAGE_SVG1";
1125         case MIME_IMAGE_VND_WAP_WBMP:
1126                 return "MIME_IMAGE_VND_WAP_WBMP";
1127
1128         case MIME_IMAGE_X_BMP:
1129                 return "MIME_IMAGE_X_BMP";
1130
1131         case MIME_MESSAGE_RFC822:
1132                 return "MIME_MESSAGE_RFC822";
1133
1134         case MIME_MULTIPART_MIXED:
1135                 return "MIME_MULTIPART_MIXED";
1136         case MIME_MULTIPART_RELATED:
1137                 return "MIME_MULTIPART_RELATED";
1138         case MIME_MULTIPART_ALTERNATIVE:
1139                 return "MIME_MULTIPART_ALTERNATIVE";
1140         case MIME_MULTIPART_FORM_DATA:
1141                 return "MIME_MULTIPART_FORM_DATA";
1142         case MIME_MULTIPART_BYTERANGE:
1143                 return "MIME_MULTIPART_BYTERANGE";
1144         case MIME_MULTIPART_REPORT:
1145                 return "MIME_MULTIPART_REPORT";
1146
1147         case MIME_TEXT_TXT:
1148                 return "MIME_TEXT_TXT";
1149         case MIME_TEXT_HTML:
1150                 return "MIME_TEXT_HTML";
1151         case MIME_TEXT_PLAIN:
1152                 return "MIME_TEXT_PLAIN";
1153         case MIME_TEXT_CSS:
1154                 return "MIME_TEXT_CSS";
1155         case MIME_TEXT_XML:
1156                 return "MIME_TEXT_XML";
1157         case MIME_TEXT_IMELODY:
1158                 return "MIME_TEXT_IMELODY";
1159         case MIME_TEXT_CALENDAR:
1160                 return "MIME_TEXT_CALENDAR";
1161         case MIME_TEXT_VND_WAP_WMLSCRIPT:
1162                 return "MIME_TEXT_VND_WAP_WMLSCRIPT";
1163         case MIME_TEXT_VND_WAP_WML:
1164                 return "MIME_TEXT_VND_WAP_WML";
1165         case MIME_TEXT_VND_WAP_WTA_EVENT:
1166                 return "MIME_TEXT_VND_WAP_WTA_EVENT";
1167         case MIME_TEXT_VND_WAP_CONNECTIVITY_XML:
1168                 return "MIME_TEXT_VND_WAP_CONNECTIVITY_XML";
1169         case MIME_TEXT_VND_WAP_SI:
1170                 return "MIME_TEXT_VND_WAP_SI";
1171         case MIME_TEXT_VND_WAP_SL:
1172                 return "MIME_TEXT_VND_WAP_SL";
1173         case MIME_TEXT_VND_WAP_CO:
1174                 return "MIME_TEXT_VND_WAP_CO";
1175         case MIME_TEXT_VND_SUN_J2ME_APP_DESCRIPTOR:
1176                 return "MIME_TEXT_VND_SUN_J2ME_APP_DESCRIPTOR";
1177         case MIME_TEXT_X_HDML:
1178                 return "MIME_TEXT_X_HDML";
1179         case MIME_TEXT_X_VCALENDAR:
1180                 return "MIME_TEXT_X_VCALENDAR";
1181         case MIME_TEXT_X_VCARD:
1182                 return "MIME_TEXT_X_VCARD";
1183         case MIME_TEXT_X_IMELODY:
1184                 return "MIME_TEXT_X_IMELODY";
1185         case MIME_TEXT_X_VTODO:
1186                 return "MIME_TEXT_X_VTODO";
1187
1188
1189         case MIME_VIDEO_MPEG4:
1190                 return "MIME_VIDEO_MPEG4";
1191         case MIME_VIDEO_MP4:
1192                 return "MIME_VIDEO_MP4";
1193         case MIME_VIDEO_H263:
1194                 return "MIME_VIDEO_H263";
1195         case MIME_VIDEO_3GPP:
1196                 return "MIME_VIDEO_3GPP";
1197         case MIME_VIDEO_3GP:
1198                 return "MIME_VIDEO_3GP";
1199         case MIME_VIDEO_AVI:
1200                 return "MIME_VIDEO_AVI";
1201         case MIME_VIDEO_SDP:
1202                 return "MIME_VIDEO_SDP";
1203         case MIME_VIDEO_MP4_ES:
1204                 return "MIME_VIDEO_MP4_ES";
1205         case MIME_VIDEO_MPEG:
1206                 return "MIME_VIDEO_MPEG";
1207         case MIME_VIDEO_VND_RN_REALVIDEO:
1208                 return "MIME_VIDEO_VND_RN_REALVIDEO";
1209         case MIME_VIDEO_X_MP4:
1210                 return "MIME_VIDEO_X_MP4";
1211         case MIME_VIDEO_X_PV_MP4:
1212                 return "MIME_VIDEO_X_PV_MP4";
1213         case MIME_VIDEO_X_PN_REALVIDEO:
1214                 return "MIME_VIDEO_X_PN_REALVIDEO";
1215         case MIME_VIDEO_X_PN_MULTIRATE_REALVIDEO:
1216                 return "MIME_VIDEO_X_PN_MULTIRATE_REALVIDEO";
1217         default:
1218                 return MmsDebugPrintUnknownValue(mimeType);
1219         }
1220 }
1221
1222
1223 /* MsgMmsMsg.h */
1224 const char *MmsDebugGetMmsReport(MmsReport report)
1225 {
1226         switch (report) {
1227         case MMS_REPORT_ERROR:
1228                 return "MMS_REPORT_ERROR";
1229         case MMS_REPORT_YES:
1230                 return "MMS_REPORT_YES";
1231         case MMS_REPORT_NO:
1232                 return "MMS_REPORT_NO";
1233         }
1234
1235         return MmsDebugPrintUnknownValue(report);
1236 }
1237
1238
1239 const char *MmsDebugGetMmsReportAllowed(MmsReportAllowed reportAllowed)
1240 {
1241         switch (reportAllowed) {
1242         case MMS_REPORTALLOWED_ERROR:
1243                 return "MMS_REPORTALLOWED_ERROR";
1244         case MMS_REPORTALLOWED_YES:
1245                 return "MMS_REPORTALLOWED_YES";
1246         case MMS_REPORTALLOWED_NO:
1247                 return "MMS_REPORTALLOWED_NO";
1248         }
1249
1250         return MmsDebugPrintUnknownValue(reportAllowed);
1251 }
1252
1253
1254 const char *MmsDebugGetMmsReadStatus(msg_read_report_status_t readStatus)
1255 {
1256         _MSG_READ_REPORT_STATUS_E readReport = (_MSG_READ_REPORT_STATUS_E)readStatus;
1257
1258         switch (readReport) {
1259         case MSG_READ_REPORT_NONE:
1260                 return "MMS_READSTATUS_NONE";
1261         case MSG_READ_REPORT_IS_READ:
1262                 return "MMS_IS_READ";
1263         case MSG_READ_REPORT_IS_DELETED:
1264                 return "MMS_IS_DELETED";
1265         default:
1266                 break;
1267         }
1268
1269         return MmsDebugPrintUnknownValue(readStatus);
1270 }
1271
1272 const char *MmsDebugGetMsgType(MmsMsgType msgType)
1273 {
1274         switch (msgType) {
1275         case MMS_MSGTYPE_ERROR:
1276                 return "error";
1277         case MMS_MSGTYPE_SEND_REQ:
1278                 return "send.req";
1279         case MMS_MSGTYPE_SEND_CONF:
1280                 return "send.conf";
1281         case MMS_MSGTYPE_NOTIFICATION_IND:
1282                 return "notification.ind";
1283         case MMS_MSGTYPE_NOTIFYRESP_IND:
1284                 return "notifyResp.ind";
1285         case MMS_MSGTYPE_RETRIEVE_CONF:
1286                 return "retrieve conf";
1287         case MMS_MSGTYPE_ACKNOWLEDGE_IND:
1288                 return "acknowledge ind";
1289         case MMS_MSGTYPE_DELIVERY_IND:
1290                 return "delivery ind";
1291         case MMS_MSGTYPE_READREC_IND:
1292                 return "read rec ind";
1293         case MMS_MSGTYPE_READORG_IND:
1294                 return "read org ind";
1295         case MMS_MSGTYPE_FORWARD_REQ:
1296                 return "forward req";
1297         case MMS_MSGTYPE_FORWARD_CONF:
1298                 return "forward conf";
1299         case MMS_MSGTYPE_READ_REPLY:
1300                 return "read reply";
1301         default:
1302                 return MmsDebugPrintUnknownValue(msgType);
1303         }
1304 }
1305
1306 const char *MmsDebugGetResponseStatus(MmsResponseStatus responseStatus)
1307 {
1308         switch (responseStatus) {
1309         case MMS_RESPSTATUS_ERROR:
1310                 return "error";
1311         case MMS_RESPSTATUS_OK:
1312                 return "ok";
1313         case MMS_RESPSTAUTS_ERROR_UNSPECIFIED:
1314                 return "unspecified";
1315         case MMS_RESPSTAUTS_ERROR_SERVICEDENIED:
1316                 return "service denied";
1317         case MMS_RESPSTAUTS_ERROR_MESSAGEFORMATCORRUPT:
1318                 return "message format corrupt";
1319         case MMS_RESPSTAUTS_ERROR_SENDINGADDRESSUNRESOLVED:
1320                 return "sending address unresolved";
1321         case MMS_RESPSTAUTS_ERROR_MESSAGENOTFOUND:
1322                 return "message not found";
1323         case MMS_RESPSTAUTS_ERROR_NETWORKPROBLEM:
1324                 return "network problem";
1325         case MMS_RESPSTAUTS_ERROR_CONTENTNOTACCEPTED:
1326                 return "content not accepted";
1327         case MMS_RESPSTAUTS_ERROR_UNSUPPORTEDMESSAGE:
1328                 return "unsupported message";
1329         case MMS_RESPSTAUTS_ERROR_TRANSIENT_FAILURE:
1330                 return "transient failure";
1331         case MMS_RESPSTAUTS_ERROR_TRANSIENT_SENDING_ADDRESS_UNRESOLVED:
1332                 return "transient sending address unresolved";
1333         case MMS_RESPSTAUTS_ERROR_TRANSIENT_MESSAGE_NOT_FOUND:
1334                 return "transient message not found";
1335         case MMS_RESPSTAUTS_ERROR_TRANSIENT_NETWORK_PROBLEM:
1336                 return "transient network problem";
1337         case MMS_RESPSTAUTS_ERROR_PERMANENT_FAILURE:
1338                 return "permanent failure";
1339         case MMS_RESPSTAUTS_ERROR_PERMANENT_SERVICE_DENIED:
1340                 return "permanent service denied";
1341         case MMS_RESPSTAUTS_ERROR_PERMANENT_MESSAGE_FORMAT_CORRUPT:
1342                 return "permanent message format corrupt";
1343         case MMS_RESPSTAUTS_ERROR_PERMANENT_SENDING_ADDRESS_UNRESOLVED:
1344                 return "permanent sending address unresolved";
1345         case MMS_RESPSTAUTS_ERROR_PERMANENT_MESSAGE_NOT_FOUND:
1346                 return "permanent message not found";
1347         case MMS_RESPSTAUTS_ERROR_PERMANENT_CONTENT_NOT_ACCEPTED:
1348                 return "permanent content not accepted";
1349         case MMS_RESPSTAUTS_ERROR_PERMANENT_REPLY_CHARGING_LIMITATIONS_NOT_MET:
1350                 return "permanent reply charging limitations not met";
1351         case MMS_RESPSTAUTS_ERROR_PERMANENT_REPLY_CHARGING_REQUEST_NOT_ACCEPTED:
1352                 return "permanent reply charging request not accepted";
1353         case MMS_RESPSTAUTS_ERROR_PERMANENT_REPLY_CHARGING_FORWARDING_DENIED:
1354                 return "permanent reply charging forwarding denied";
1355         case MMS_RESPSTAUTS_ERROR_PERMANENT_REPLY_CHARGING_NOT_SUPPORTED:
1356                 return "permanent reply charging not supported";
1357         }
1358
1359         return MmsDebugPrintUnknownValue(responseStatus);
1360 }
1361
1362
1363 const char *MmsDebugGetRetrieveStatus(MmsRetrieveStatus retrieveStatus)
1364 {
1365         switch (retrieveStatus) {
1366         case MMS_RETRSTATUS_ERROR:
1367                 return "error";
1368         case MMS_RETRSTATUS_OK:
1369                 return "ok";
1370         case MMS_RETRSTATUS_TRANSIENT_FAILURE:
1371                 return "transient failure";
1372         case MMS_RETRSTATUS_TRANSIENT_MESSAGE_NOT_FOUND:
1373                 return "transient message not found";
1374         case MMS_RETRSTATUS_TRANSIENT_NETWORK_PROBLEM:
1375                 return "transient network problem";
1376         case MMS_RETRSTATUS_PERMANENT_FAILURE:
1377                 return "permanent failure";
1378         case MMS_RETRSTATUS_PERMANENT_SERVICE_DENIED:
1379                 return "permanent service denied";
1380         case MMS_RETRSTATUS_PERMANENT_MESSAGE_NOT_FOUND:
1381                 return "permanent message not found";
1382         case MMS_RETRSTATUS_PERMANENT_CONTENT_UNSUPPORT:
1383                 return "permanent content unsupport";
1384         }
1385
1386         return MmsDebugPrintUnknownValue(retrieveStatus);
1387 }
1388
1389
1390 const char *MmsDebugGetMsgStatus(msg_delivery_report_status_t msgStatus)
1391 {
1392         switch (msgStatus) {
1393         case MSG_DELIVERY_REPORT_ERROR:
1394                 return "error";
1395         case MSG_DELIVERY_REPORT_EXPIRED:
1396                 return "expired";
1397         case MSG_DELIVERY_REPORT_SUCCESS:
1398                 return "retrieved";
1399         case MSG_DELIVERY_REPORT_REJECTED:
1400                 return "rejected";
1401         case MSG_DELIVERY_REPORT_DEFERRED:
1402                 return "deferred";
1403         case MSG_DELIVERY_REPORT_UNRECOGNISED:
1404                 return "unrecognised";
1405         case MSG_DELIVERY_REPORT_INDETERMINATE:
1406                 return "indeterminate";
1407         case MSG_DELIVERY_REPORT_FORWARDED:
1408                 return "forwarded";
1409         case MSG_DELIVERY_REPORT_UNREACHABLE:
1410                 return "unreachable";
1411         }
1412
1413         return MmsDebugPrintUnknownValue(msgStatus);
1414 }
1415
1416
1417 const char *MmsDebugGetMsgClass(MmsMsgClass msgClass)
1418 {
1419         switch (msgClass) {
1420         case MMS_MSGCLASS_ERROR:
1421                 return "error";
1422         case MMS_MSGCLASS_PERSONAL:
1423                 return "personal";
1424         case MMS_MSGCLASS_ADVERTISEMENT:
1425                 return "advertisement";
1426         case MMS_MSGCLASS_INFORMATIONAL:
1427                 return "information";
1428         case MMS_MSGCLASS_AUTO:
1429                 return "auto";
1430         }
1431
1432         return MmsDebugPrintUnknownValue(msgClass);
1433 }
1434
1435
1436 const char *MmsDebugGetDataType(MmsDataType dataType)
1437 {
1438         switch (dataType) {
1439         case MMS_DATATYPE_NONE:
1440                 return "MMS_DATATYPE_NONE";
1441         case MMS_DATATYPE_READ:
1442                 return "MMS_DATATYPE_READ";
1443         case MMS_DATATYPE_SENT:
1444                 return "MMS_DATATYPE_SENT";
1445         case MMS_DATATYPE_NOTIFY:
1446                 return "MMS_DATATYPE_NOTIFY";
1447         case MMS_DATATYPE_UNSENT:
1448                 return "MMS_DATATYPE_UNSENT";
1449         case MMS_DATATYPE_DRAFT:
1450                 return "MMS_DATATYPE_DRAFT";
1451         case MMS_DATATYPE_SENDING:
1452                 return "MMS_DATATYPE_SENDING";
1453         case MMS_DATATYPE_DRM_RO_WAITING:
1454                 return "MMS_DATATYPE_DRM_RO_WAITING";
1455         case MMS_DATATYPE_RETRIEVING:
1456                 return "MMS_DATATYPE_RETRIEVING";
1457         case MMS_DATATYPE_UNRETV:
1458                 return "MMS_DATATYPE_UNRETV";
1459         default:
1460                 return MmsDebugPrintUnknownValue(dataType);
1461         }
1462 }
1463
1464 bool MmsInitMsgType(MsgType *pMsgType)
1465 {
1466         MSG_DEBUG("ptr : [%p]", pMsgType);
1467         pMsgType->offset = 0;
1468         pMsgType->size = 0;
1469         pMsgType->contentSize = 0;
1470         pMsgType->disposition = -1;
1471         pMsgType->encoding = -1;
1472         pMsgType->type = MIME_UNKNOWN;
1473         pMsgType->section = -1;
1474
1475         pMsgType->szOrgFilePath[0] = '\0';
1476         pMsgType->szContentID[0] = '\0';
1477         pMsgType->szContentLocation[0] = '\0';
1478
1479         MmsInitMsgContentParam(&pMsgType->param);
1480         MmsInitMsgDRMInfo(&pMsgType->drmInfo);
1481
1482         return true;
1483 }
1484
1485 bool MmsInitMsgBody(MsgBody *pMsgBody)
1486 {
1487         MSG_DEBUG("ptr : [%p]", pMsgBody);
1488         pMsgBody->offset = 0;
1489         pMsgBody->size = 0;
1490         pMsgBody->body.pText = NULL;
1491
1492         MmsInitMsgType(&pMsgBody->presentationType);
1493         pMsgBody->pPresentationBody = NULL;
1494
1495         memset(pMsgBody->szOrgFilePath, 0, MSG_FILEPATH_LEN_MAX);
1496
1497         return true;
1498 }
1499
1500 bool MmsInitMsgContentParam(MsgContentParam *pMsgContentParam)
1501 {
1502         MSG_DEBUG("ptr : [%p]", pMsgContentParam);
1503         pMsgContentParam->charset = MSG_CHARSET_UNKNOWN;
1504         pMsgContentParam->type = MIME_UNKNOWN;
1505         pMsgContentParam->szBoundary[0] = '\0';
1506         pMsgContentParam->szFileName[0] = '\0';
1507         pMsgContentParam->szName[0] = '\0';
1508         pMsgContentParam->szStart[0] = '\0';
1509         pMsgContentParam->szStartInfo[0] = '\0';
1510         pMsgContentParam->pPresentation = NULL;
1511         pMsgContentParam->reportType = MSG_PARAM_REPORT_TYPE_UNKNOWN; // only used as parameter of Content-Type: multipart/report; report-type
1512 #ifdef FEATURE_JAVA_MMS
1513         pMsgContentParam->szApplicationID = NULL;
1514         pMsgContentParam->szReplyToApplicationID = NULL;
1515 #endif
1516         return true;
1517 }
1518
1519 bool MmsInitMsgAttrib(MmsAttrib *pAttrib)
1520 {
1521         MSG_DEBUG("MmsInitMsgAttrib");
1522
1523         pAttrib->bAskDeliveryReport = false;
1524
1525         pAttrib->bAskReadReply = false;
1526         pAttrib->bRead = false;
1527         pAttrib->bReportAllowed = false;
1528         pAttrib->readReportAllowedType = MMS_RECEIVE_READ_REPORT_ALLOWED;
1529         pAttrib->readReportSendStatus = MMS_RECEIVE_READ_REPORT_NO_SEND;
1530         pAttrib->bReadReportSent = false;
1531
1532         pAttrib->bHideAddress = false;
1533         pAttrib->date = 0;
1534
1535         pAttrib->deliveryTime.type = MMS_TIMETYPE_RELATIVE;
1536         pAttrib->deliveryTime.time = 0;
1537
1538         pAttrib->expiryTime.type = MMS_TIMETYPE_RELATIVE;
1539         pAttrib->expiryTime.time = 0;
1540
1541         memset(&pAttrib->expiryTime, 0, sizeof(MmsTimeStruct));
1542         pAttrib->msgClass = MMS_MSGCLASS_PERSONAL;
1543         pAttrib->msgStatus = MSG_DELIVERY_REPORT_NONE;
1544         pAttrib->priority = MMS_PRIORITY_NORMAL;
1545         pAttrib->responseStatus = MMS_RESPSTATUS_ERROR;
1546         pAttrib->retrieveStatus = MMS_RETRSTATUS_ERROR;
1547         pAttrib->contentType = MIME_UNKNOWN;
1548         pAttrib->msgSize = 0;
1549         pAttrib->bLeaveCopy = true;
1550         pAttrib->version = MMS_VERSION;
1551
1552         memset(pAttrib->szFrom, 0, MSG_LOCALE_ADDR_LEN + 10);
1553         memset(pAttrib->szResponseText, 0, MMS_LOCALE_RESP_TEXT_LEN + 1);
1554         memset(pAttrib->szRetrieveText, 0, MMS_LOCALE_RESP_TEXT_LEN + 1);
1555         memset(pAttrib->szSubject, 0, MSG_LOCALE_SUBJ_LEN + 1);
1556         pAttrib->szTo = NULL;
1557         pAttrib->szCc = NULL;
1558         pAttrib->szBcc = NULL;
1559
1560         pAttrib->pMultiStatus = NULL;
1561
1562         pAttrib->replyCharge.chargeType = MMS_REPLY_NONE;
1563         memset(&pAttrib->replyCharge.deadLine , 0, sizeof(MmsTimeStruct));
1564         pAttrib->replyCharge.chargeSize = 0;
1565         memset(pAttrib->replyCharge.szChargeID, 0, MMS_MSG_ID_LEN);
1566
1567         return true;
1568 }
1569
1570
1571 bool MmsInitMsgDRMInfo(MsgDRMInfo *pMsgDrmInfo)
1572 {
1573         MSG_DEBUG("ptr : [%p]", pMsgDrmInfo);
1574         pMsgDrmInfo->contentType = MIME_UNKNOWN;
1575         pMsgDrmInfo->drmType = MSG_DRM_TYPE_NONE;
1576
1577         pMsgDrmInfo->szContentName = NULL;
1578         pMsgDrmInfo->szContentURI = NULL;
1579         pMsgDrmInfo->szContentDescription = NULL;
1580         pMsgDrmInfo->szContentVendor = NULL;
1581         pMsgDrmInfo->szRightIssuer = NULL;
1582         pMsgDrmInfo->szDrm2FullPath = NULL;
1583         pMsgDrmInfo->roWaitingTimerMax = 0;
1584         pMsgDrmInfo->bFwdLock = false;
1585         pMsgDrmInfo->bNoScreen = false;
1586         pMsgDrmInfo->bNoRingTone = false;
1587         pMsgDrmInfo->pszContentType = NULL;
1588
1589         return true;
1590 }
1591
1592 void MmsReleaseMsgDRMInfo(MsgDRMInfo *pDrmInfo)
1593 {
1594         MSG_DEBUG("_MsgFreeDRMInfo: S T A R T  !!! \n");
1595
1596         if (pDrmInfo == NULL) {
1597                 MSG_DEBUG("pDrmInfo is NULL");
1598                 return;
1599         }
1600
1601         if (pDrmInfo->szContentDescription) {
1602                 free(pDrmInfo->szContentDescription);
1603                 pDrmInfo->szContentDescription = NULL;
1604         }
1605
1606         if (pDrmInfo->szContentVendor) {
1607                 free(pDrmInfo->szContentVendor);
1608                 pDrmInfo->szContentVendor = NULL;
1609         }
1610
1611         if (pDrmInfo->szContentName) {
1612                 free(pDrmInfo->szContentName);
1613                 pDrmInfo->szContentName = NULL;
1614         }
1615
1616         if (pDrmInfo->szContentURI) {
1617                 free(pDrmInfo->szContentURI);
1618                 pDrmInfo->szContentURI = NULL;
1619         }
1620
1621         if (pDrmInfo->szRightIssuer) {
1622                 free(pDrmInfo->szRightIssuer);
1623                 pDrmInfo->szRightIssuer = NULL;
1624         }
1625
1626         if (pDrmInfo->szDrm2FullPath) {
1627                 free(pDrmInfo->szDrm2FullPath);
1628                 pDrmInfo->szDrm2FullPath = NULL;
1629         }
1630
1631         pDrmInfo->contentType = MIME_UNKNOWN;
1632         pDrmInfo->drmType = MSG_DRM_TYPE_NONE;
1633 }
1634
1635
1636 bool MmsReleaseMmsAttrib(MmsAttrib *pAttrib)
1637 {
1638         MSG_BEGIN();
1639
1640         if (pAttrib == NULL) {
1641                 MSG_DEBUG("pAttrib is NULL");
1642                 return false;
1643         }
1644
1645         if (pAttrib->szTo) {
1646                 free(pAttrib->szTo);
1647                 pAttrib->szTo = NULL;
1648         }
1649
1650         if (pAttrib->szCc) {
1651                 free(pAttrib->szCc);
1652                 pAttrib->szCc = NULL;
1653         }
1654
1655         if (pAttrib->szBcc) {
1656                 free(pAttrib->szBcc);
1657                 pAttrib->szBcc = NULL;
1658         }
1659
1660         //check if pMultiStatus should be freed or not, because pMultiStatus is not allocated
1661         if (pAttrib->pMultiStatus) {
1662                 MmsMsgMultiStatus *pMultiStatus = pAttrib->pMultiStatus;
1663                 MmsMsgMultiStatus *pCurStatus = NULL;
1664
1665                 while (pMultiStatus != NULL ) {
1666                         pCurStatus = pMultiStatus;
1667                         pMultiStatus = pMultiStatus->pNext;
1668
1669                         if (pCurStatus) {
1670                                 free(pCurStatus);
1671                                 pCurStatus = NULL;
1672                         }
1673                 }
1674
1675                 pAttrib->pMultiStatus = NULL;
1676         }
1677
1678
1679         MSG_END();
1680
1681         return true;
1682 }
1683
1684 bool MmsReleaseMsgBody(MsgBody *pBody, int type)
1685 {
1686         MSG_BEGIN();
1687
1688         if (pBody == NULL) {
1689                 MSG_DEBUG("pBody == NULL \n" );
1690                 MSG_END();
1691
1692                 return false;
1693         }
1694
1695         switch (type) {
1696         case MIME_MULTIPART_REPORT:
1697         case MIME_APPLICATION_VND_OMA_DRM_MESSAGE:
1698         case MIME_APPLICATION_VND_WAP_MULTIPART_MIXED:
1699         case MIME_APPLICATION_VND_WAP_MULTIPART_RELATED:
1700         case MIME_APPLICATION_VND_WAP_MULTIPART_ASTERIC:
1701         case MIME_MULTIPART_MIXED:
1702         case MIME_MULTIPART_RELATED:
1703         case MIME_MULTIPART_ALTERNATIVE:
1704         case MIME_APPLICATION_VND_WAP_MULTIPART_ALTERNATIVE:
1705                 {
1706                         MsgMultipart *pMulti = pBody->body.pMultipart;
1707                         MsgMultipart *pCurrPart = NULL;
1708                         MsgBody *pPresentation = pBody->pPresentationBody;
1709                         while (pMulti != NULL) {
1710                                 pCurrPart = pMulti;
1711
1712                                 pMulti = pMulti->pNext;
1713
1714                                 if (pCurrPart) {
1715                                         MmsReleaseMsgDRMInfo(&pCurrPart->type.drmInfo);
1716
1717                                         if (pCurrPart->pBody) {
1718                                                 if (pCurrPart->pBody->body.pText) {
1719                                                         free(pCurrPart->pBody->body.pText);
1720                                                         pCurrPart->pBody->body.pText = NULL;
1721                                                 }
1722
1723                                                 free(pCurrPart->pBody);
1724                                                 pCurrPart->pBody = NULL;
1725                                         }
1726                                         free(pCurrPart);
1727                                         pCurrPart = NULL;
1728                                 }
1729                         }
1730
1731                         pBody->body.pMultipart = NULL;
1732
1733                         if (pPresentation) {
1734                                 if (pPresentation->body.pText) {
1735                                         free(pPresentation->body.pText);
1736                                         pPresentation->body.pText = NULL;
1737                                 }
1738                                 free(pPresentation);
1739                                 pBody->pPresentationBody = NULL;
1740                         }
1741
1742                         MmsInitMsgType(&pBody->presentationType);
1743
1744                         break;
1745                 }
1746
1747         default:
1748                 /* Any single part */
1749                 if (pBody->body.pText) {
1750                         free(pBody->body.pText);
1751                         pBody->body.pText = NULL;
1752                 }
1753
1754                 break;
1755         }
1756
1757         MSG_END();
1758         return true;
1759 }
1760
1761 void MmsReleaseMmsMsg(MmsMsg *pMmsMsg)
1762 {
1763         if (pMmsMsg) {
1764                 MmsReleaseMsgBody(&pMmsMsg->msgBody, pMmsMsg->msgType.type);
1765                 MmsReleaseMmsAttrib(&pMmsMsg->mmsAttrib);
1766                 bzero(pMmsMsg, sizeof(MmsMsg));
1767         }
1768 }
1769
1770 bool MmsPrintMulitpart(MsgMultipart *pMultipart, int index)
1771 {
1772         MSG_DEBUG("------------------------------");
1773         MSG_INFO("[%dth] multipart info", index);
1774         MSG_INFO("header size [%d], body size [%d]", pMultipart->type.size, pMultipart->type.contentSize);
1775         MSG_SEC_INFO("content type [%s]", MmsDebugGetMimeType((MimeType)pMultipart->type.type));
1776         MSG_SEC_INFO("content ID [%s]", pMultipart->type.szContentID);
1777         MSG_SEC_INFO("content location [%s]", pMultipart->type.szContentLocation);
1778         MSG_SEC_INFO("parameter Name [%s]", pMultipart->type.param.szName);
1779         MSG_SEC_INFO("parameter Filename[%s]", pMultipart->type.param.szFileName);
1780
1781         if (pMultipart->type.type == MIME_TEXT_PLAIN) {
1782                 MSG_SEC_INFO("text info : charset [%d], name [%s]", pMultipart->type.param.charset, pMultipart->type.param.szName);
1783         }
1784
1785         if (pMultipart->type.drmInfo.drmType != MSG_DRM_TYPE_NONE) {
1786                 MSG_INFO("drm info");
1787                 MSG_INFO("drm type [%d] (0: NONE 1: Fowward Lock, 2:Combined Delivery, 3: Separated Delivery)", pMultipart->type.drmInfo.drmType);
1788                 MSG_SEC_INFO("drm content type [%s]", MmsDebugGetMimeType((MimeType)pMultipart->type.drmInfo.contentType));
1789                 MSG_SEC_INFO("drm content URI [%s]", pMultipart->type.drmInfo.szContentURI);
1790                 MSG_INFO("drm2FullPath [%s]", pMultipart->type.drmInfo.szDrm2FullPath);
1791         }
1792
1793         MSG_DEBUG("------------------------------");
1794         return true;
1795 }
1796
1797 bool MmsIsTextType(int type)
1798 {
1799         if (type == MIME_TEXT_PLAIN
1800                 || type == MIME_TEXT_HTML
1801                 || type == MIME_TEXT_VND_WAP_WML
1802                 || type == MIME_TEXT_X_VNOTE
1803                 || type == MIME_APPLICATION_SMIL
1804                 || type == MIME_TEXT_X_IMELODY)
1805         {
1806                 return true;
1807         } else {
1808                 return false;
1809         }
1810 }
1811
1812 bool MmsIsMultipart(int type)
1813 {
1814         if (type == MIME_MULTIPART_RELATED
1815                 || type == MIME_APPLICATION_VND_WAP_MULTIPART_MIXED
1816                 || type == MIME_APPLICATION_VND_WAP_MULTIPART_RELATED
1817                 || type == MIME_APPLICATION_VND_WAP_MULTIPART_ASTERIC
1818                 || type == MIME_MULTIPART_MIXED
1819                 || type == MIME_MULTIPART_REPORT) {
1820                 return true;
1821         } else {
1822                 return false;
1823         }
1824 }
1825
1826 bool MmsIsVitemContent(int type, char *pszName)
1827 {
1828         switch (type) {
1829         case MIME_TEXT_X_VCARD:
1830         case MIME_TEXT_X_VCALENDAR:
1831         case MIME_TEXT_X_VNOTE: // vnt
1832         case MIME_TEXT_X_VTODO:
1833         case MIME_TEXT_PLAIN:   // vbm - It SHOULD be distinguished from a normal text file.
1834         {
1835                 char *pszExt = NULL;
1836
1837                 if (!pszName)
1838                         break;
1839
1840                 // search file extension.
1841                 if ((pszExt = strrchr(pszName, '.')) == NULL)
1842                         break;
1843
1844                 if (!strcasecmp(pszExt, ".vbm")) {
1845                         return true;
1846                 }
1847
1848                 if (!strcasecmp(pszExt, ".vcs")) {
1849                         return true;
1850                 }
1851
1852                 if (!strcasecmp(pszExt, ".vcf")) {
1853                         return true;
1854                 }
1855
1856                 if (!strcasecmp(pszExt, ".vnt")) {
1857                         return true;
1858                 }
1859
1860                 if (!strcasecmp(pszExt, ".vts")) {
1861                         return true;
1862                 }
1863
1864                 break;
1865         }
1866         default:
1867                 break;
1868         }
1869
1870         MSG_DEBUG("MmsIsVitemContent false.");
1871         return false;
1872 }
1873
1874 MsgMultipart *MmsAllocMultipart(void)
1875 {
1876         MsgMultipart *pMultipart = NULL;
1877
1878         pMultipart = (MsgMultipart *)malloc(sizeof(MsgMultipart));
1879
1880         if (pMultipart == NULL)
1881                 goto __CATCH;
1882
1883         pMultipart->pBody = (MsgBody *)malloc(sizeof(MsgBody));
1884
1885         if (pMultipart->pBody == NULL)
1886                 goto __CATCH;
1887
1888         MmsInitMsgType(&pMultipart->type);
1889         MmsInitMsgBody(pMultipart->pBody);
1890
1891         pMultipart->pNext = NULL;
1892
1893         return pMultipart;
1894
1895 __CATCH:
1896
1897         if (pMultipart) {
1898                 if (pMultipart->pBody) {
1899                         free(pMultipart->pBody);
1900                         pMultipart->pBody = NULL;
1901                 }
1902
1903                 free(pMultipart);
1904                 pMultipart = NULL;
1905         }
1906
1907         return NULL;
1908 }