Merge from master.
[framework/messaging/msg-service.git] / plugin / mms_plugin / MmsPluginDecode.cpp
1 /*
2 * Copyright 2012-2013  Samsung Electronics Co., Ltd
3 *
4 * Licensed under the Flora License, Version 1.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://floralicense.org
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 <stdio.h>
18 #include <string.h>
19 #include <sys/stat.h>
20 #include <stdlib.h>
21 #include <errno.h>
22
23 #include "MsgUtilFile.h"
24
25 #include "MmsPluginDebug.h"
26 #include "MmsPluginDecode.h"
27 #include "MmsPluginCodecCommon.h"
28 #include "MmsPluginStorage.h"
29 #include "MmsPluginDebug.h"
30 #include "MmsPluginMIME.h"
31 #include "MmsPluginAvCodec.h"
32 #include "MmsPluginSmil.h"
33 #include "MmsPluginTextConvert.h"
34 #include "MmsPluginUtil.h"
35
36 #ifdef __SUPPORT_DRM__
37 #include "MmsPluginDrm.h"
38 #include "MsgDrmWrapper.h"
39 #endif
40
41
42 /*Decode wsp*/
43 static int __MmsGetDecodeOffset(void);
44 static bool __MmsDecodeInitialize(void);
45 static void __MmsCleanDecodeBuff(void);
46 static bool __MmsBinaryDecodeMovePointer(FILE *pFile, int offset, int totalLength);
47 static bool     __MmsBinaryDecodeCheckAndDecreaseLength(int *pLength, int valueLength);
48
49 static bool __MmsBinaryDecodeGetBytes(FILE *pFile, char *szBuff, int bufLen, int totalLength);          /* bufLen < gMmsDecodeMaxLen */
50 static bool __MmsBinaryDecodeGetLongBytes(FILE *pFile, char *szBuff, int bufLen, int totalLength);      /* no bufLen limit */
51 static bool __MmsBinaryDecodeGetOneByte(FILE *pFile, UINT8 *pOneByte, int totalLength);
52
53 static UINT32 __MmsHeaderDecodeIntegerByLength(FILE *pFile, UINT32 length, int totalLength);
54
55 static bool __MmsBinaryDecodeInteger(FILE *pFile, UINT32 *pInteger, int *pIntLen, int totalLength);
56 static bool __MmsDecodeLongInteger(FILE *pFile, UINT32 *pLongInteger, int totalLength);
57 static int __MmsBinaryDecodeUintvar(FILE *pFile, UINT32 *pUintVar, int totalLength);
58 static int __MmsDecodeValueLength(FILE *pFile, UINT32 *pValueLength, int totalLength);
59 static int __MmsDecodeValueLength2(FILE *pFile, UINT32 *pValueLength, int totalLength);
60 static int __MmsBinaryDecodeText(FILE *pFile, char *szBuff, int bufLen, int totalLength);
61 static char *__MmsBinaryDecodeText2(FILE *pFile, int totalLength, int *pLength);
62 static int __MmsBinaryDecodeQuotedString(FILE *pFile, char *szBuff, int bufLen, int totalLength);
63 static bool __MmsBinaryDecodeEncodedString(FILE *pFile, char *szBuff, int bufLen, int totalLength);
64
65 static bool __MmsBinaryDecodeCharset(FILE *pFile, UINT32 *nCharSet, int *pCharSetLen, int totalLength);
66 static int __MmsDecodeGetFilename(FILE *pFile, char *szBuff, int bufLen, int totalLength);
67 static MsgHeaderAddress *__MmsDecodeEncodedAddress(FILE *pFile, int totalLength);
68
69 static bool __MmsBinaryDecodeMultipart(FILE *pFile, char *szFilePath, MsgType *pMsgType, MsgBody *pMsgBody, int totalLength);
70 static bool __MmsBinaryDecodeEachPart(FILE *pFile, char *szFilePath, MsgType *pMsgType, MsgBody *pMsgBody, int totalLength);
71 static bool __MmsBinaryDecodePartHeader(FILE *pFile, MsgType *pMsgType, int headerLen, int totalLength);
72 static bool __MmsBinaryDecodePartBody(FILE *pFile, UINT32 bodyLength, int totalLength);
73 static bool __MmsBinaryDecodeEntries(FILE *pFile, UINT32 *npEntries, int totalLength);
74 static bool __MmsBinaryDecodeParameter(FILE *pFile, MsgType *pMsgType, int valueLength, int totalLength);
75
76 static int __MmsBinaryDecodeContentType(FILE *pFile, MsgType *pMsgType, int totalLength);
77
78 #ifdef __SUPPORT_DRM__
79 static bool __MmsBinaryDecodeDRMContent(FILE *pFile, char *szFilePath, MsgType *pMsgType, MsgBody *pMsgBody, unsigned int bodyLength, int totalLength);
80 #endif
81
82 //util funcion
83 static void __MsgRemoveFilePath(char *pSrc);
84 static bool __MsgChangeSpace(char *pOrg, char **ppNew);
85 static void __MsgConfirmPresentationPart(MsgType *pMsgType, MsgBody *pMsgBody, MsgPresentaionInfo *pPresentationInfo);
86 static MsgPresentationFactor __MsgIsPresentationEx(MsgType *multipartType, char* szStart, MimeType typeParam);
87 static bool __MsgLoadDataToDecodeBuffer(FILE *pFile, char **ppBuf, int *pPtr, int *pOffset, char *pInBuf1, char *pInBuf2, int maxLen, int *npRead, int endOfFile);
88 static bool __MsgFreeHeaderAddress(MsgHeaderAddress *pAddr);
89 static bool __MsgCheckFileNameHasInvalidChar(char *szName);
90
91 static bool __MsgReplaceInvalidFileNameChar(char *szInText, char replaceChar);
92 static char *__MsgGetStringUntilDelimiter(char *pszString, char delimiter);
93 static bool __MsgParseParameter(MsgType *pType, char *pSrc);
94 static char *__MsgSkipWS(char *s);
95 static char *__MsgSkipComment(char *s, long trim);
96 static MsgMultipart *__MsgAllocMultipart(void);
97
98 static char *__MsgConvertLatin2UTF8FileName(char *pSrc);
99 static bool __MsgIsUTF8String(unsigned char *szSrc, int nChar);
100 static bool __MsgIsPercentSign(char *pSrc);
101 static bool __MsgIsMultipartRelated(int type);
102 static bool __MsgIsPresentablePart(int type);
103 static bool __MsgIsText(int type);
104 static bool __MsgResolveNestedMultipart(MsgType *pPartType, MsgBody *pPartBody);
105 static bool __MsgIsHexChar(char *pSrc);
106 static char __MsgConvertHexValue(char *pSrc);
107 static int __MsgConvertCharToInt(char ch);
108 static bool __MsgCopyNestedMsgType(MsgType *pMsgType1, MsgType *pMsgType2);
109 static bool __MsgCopyNestedMsgParam(MsgContentParam *pParam1, MsgContentParam *pParam2);
110 static bool __MsgIsMultipartMixed(int type);
111
112 static bool __MsgIsInvalidFileNameChar(char ch);
113
114 static int __MsgGetLatin2UTFCodeSize(unsigned char *szSrc, int nChar);
115 static int __MsgLatin5code2UTF(unsigned char *des, int outBufSize, unsigned char *szSrc, int nChar);
116 static int __MsgGetLatin52UTFCodeSize(unsigned char *szSrc, int nChar);
117 static int __MsgLatin2UTF(unsigned char *des, int outBufSize, unsigned char *szSrc, int nChar);
118 static int __MsgLatin7code2UTF(unsigned char *des, int outBufSize, unsigned char *szSrc, int nChar);
119 static int __MsgGetLatin72UTFCodeSize(unsigned char *szSrc, int nChar);
120 static int __MsgUnicode2UTF(unsigned char *des, int outBufSize, unsigned short *szSrc, int nChar);
121 static int __MsgGetUnicode2UTFCodeSize(unsigned short *szSrc, int nChar);
122 static bool __MmsAddrUtilCheckEmailAddress(char *pszAddr);
123 static int __MsgCutUTFString(unsigned char *des, int outBufSize, unsigned char *szSrc, int nChar);
124 static void __MsgMIMERemoveQuote(char *szSrc);
125 static bool __MmsMultipartSaveAsTempFile(MsgType *pPartType, MsgBody *pPartBody, char *pszMailboxPath, char *pszMsgFilename, int index, bool bSave);
126
127 static bool __MmsGetMediaPartData(MsgType *pPartType, MsgBody *pPartBody, FILE *pFile);
128 static char *__MmsGetBinaryUTF8Data(char *pData, int nRead, int msgEncodingValue, int msgTypeValue, int msgCharsetValue, int *npRead);
129
130 #ifndef __SUPPORT_DRM__
131 static bool __MsgMakeFileName(int iMsgType, char *szFileName, int nUntitleIndex);
132 #else
133 static bool __MsgMakeFileName(int iMsgType, char *szFileName, MsgDrmType drmType, int nUntitleIndex);
134 #endif
135
136 static bool __MmsDebugPrintMulitpartEntry(MsgMultipart *pMultipart, int index);
137
138 static char gszMmsLoadBuf1[MSG_MMS_DECODE_BUFFER_MAX + 1] = {0, };
139 static char gszMmsLoadBuf2[MSG_MMS_DECODE_BUFFER_MAX + 1] = {0, };
140
141 static char *gpCurMmsDecodeBuff = NULL;
142 static int gCurMmsDecodeBuffPos = 0;    /* next decoding position in gpCurMmsDecodeBuff  */
143 static int gMmsDecodeMaxLen = 0;
144 static int gMmsDecodeCurOffset = 0;     /* current offset in file (last read) */
145 static int gMmsDecodeBufLen = 0;                /* number of last read characters */
146
147 static char *gpMmsDecodeBuf1 = NULL;
148 static char *gpMmsDecodeBuf2 = NULL;
149
150 MmsHeader       mmsHeader =
151 {
152         false,                                                                  //bActive
153         NULL,                                                                   //pszOwner
154         -1,                                                                             //msgID
155
156         (MmsMsgType)MMS_MSGTYPE_ERROR,                  //MmsMsgType                    iType;
157         "",                                                                             //char[]                                szTrID;
158         //"",                                                                           //short int                             version;
159         0,                                                                              //short int                             version;
160         0,                                                                              //UINT32                                date;
161
162         NULL,                                                                   //MsgHeaderAddress*             pFrom;
163         NULL,                                                                   //MsgHeaderAddress*             pTo;
164         NULL,                                                                   //MsgHeaderAddress*             pCc;
165         NULL,                                                                   //MsgHeaderAddress*             pBcc;
166         "",                                                                             //char[]                                szSubject;
167         (MmsResponseStatus)MMS_RESPSTATUS_OK,   //MmsResponseStatus             iResponseStatus;
168         (MmsRetrieveStatus)MMS_RETRSTATUS_OK,   //MmsRetrieveStatus             iRetrieveStatus;
169         "",                                                                             //char[]                                szResponseText;
170         "",                                                                             //char[]                                szRetrieveText;
171
172
173         /* has default value in specification */
174
175         (MmsMsgClass)MMS_MSGCLASS_PERSONAL,             //MmsMsgClass                   msgClass;
176         {MMS_TIMETYPE_RELATIVE, 0},                             //MmsTimeStruct                 expiryTime;
177         {MMS_TIMETYPE_RELATIVE, 0},                             //MmsTimeStruct                 deliveryTime;
178         (MmsPriority)MMS_PRIORITY_NORMAL,               //MmsPriority                   priority;               // Refer [OMA-MMS-ENC-v1_2-20030915-C]
179         (MmsSenderVisible)MMS_SENDER_SHOW,              //MmsSenderVisible              senderVisible;
180         (MmsReport)MMS_REPORT_NO,                               //MmsReport                             deliveryReport;
181         (MmsReport)MMS_REPORT_NO,                               //MmsReport                             readReply;
182         (MmsReportAllowed)MMS_REPORTALLOWED_NO,//MmsReportAllowed               iReportAllowed;
183         "",                                                                             //char[]                                szContentLocation;
184
185
186         /* there is no right default value */
187
188         (msg_delivery_report_status_t)MSG_DELIVERY_REPORT_NONE,         //MmsMsgStatus                  iMsgStatus;
189         (msg_read_report_status_t)MSG_READ_REPORT_NONE,         //MmsReadStatus                 readStatus;
190
191         /* MMS v1.1 ReplyCharge */
192         {
193                 (MmsReplyChargeType)MMS_REPLY_NONE,     //MmsReplyChargeType    chargeType;
194                 {MMS_TIMETYPE_RELATIVE, 0},                     //MmsTimeStruct                 deadLine;
195                 0,                                                                      //int                                   chargeSize;
196                 "" ,                                                            //char                                  szChargeID;
197         },
198
199         "",                                                                             //char[]                                szMsgID;
200         0,                                                                              //UINT32                                msgSize;
201 };
202
203 #ifdef __SUPPORT_DRM__
204
205 #define MMS_DRM2_CONVERT_BUFFER_MAX     4*1024
206 const UINT32 MMS_UINTVAR_LENGTH_1 =  0x0000007f;                //7bit
207 const UINT32 MMS_UINTVAR_LENGTH_2 =  0x00003fff;                //14bit
208 const UINT32 MMS_UINTVAR_LENGTH_3 =  0x001fffff;                //21bit
209 #endif
210
211 static bool __MmsDecodeInitialize(void)
212 {
213         MmsInitMsgType(&mmsHeader.msgType);
214         MmsInitMsgBody(&mmsHeader.msgBody);
215         return true;
216 }
217
218 void MmsInitHeader()
219 {
220         mmsHeader.type = MMS_MSGTYPE_ERROR;
221
222         memset(mmsHeader.szTrID, 0, MMS_TR_ID_LEN + 1);
223         mmsHeader.version = MMS_VERSION;
224         mmsHeader.date = 0;
225
226         __MsgFreeHeaderAddress(mmsHeader.pFrom);
227         __MsgFreeHeaderAddress(mmsHeader.pTo);
228         __MsgFreeHeaderAddress(mmsHeader.pCc);
229         __MsgFreeHeaderAddress(mmsHeader.pBcc);
230
231         mmsHeader.pFrom = NULL;
232         mmsHeader.pTo = NULL;
233         mmsHeader.pCc = NULL;
234         mmsHeader.pBcc = NULL;
235
236         memset(mmsHeader.szSubject, 0, MSG_LOCALE_SUBJ_LEN + 1);
237
238         mmsHeader.responseStatus = (MmsResponseStatus)MMS_RESPSTATUS_OK;
239         mmsHeader.retrieveStatus = (MmsRetrieveStatus)MMS_RETRSTATUS_OK;
240         memset(mmsHeader.szResponseText, 0, MMS_LOCALE_RESP_TEXT_LEN + 1);
241         memset(mmsHeader.szRetrieveText, 0, MMS_LOCALE_RESP_TEXT_LEN + 1);
242
243
244         mmsHeader.msgClass = (MmsMsgClass)MMS_MSGCLASS_PERSONAL;
245         mmsHeader.expiryTime.type = MMS_TIMETYPE_RELATIVE;
246         mmsHeader.expiryTime.time = 0;
247         mmsHeader.deliveryTime.type     = MMS_TIMETYPE_RELATIVE;
248         mmsHeader.deliveryTime.time     = 0;
249         mmsHeader.priority = (MmsPriority)MMS_PRIORITY_NORMAL;  // Refer [OMA-MMS-ENC-v1_2-20030915-C]
250         mmsHeader.hideAddress =(MmsSenderVisible)MMS_SENDER_SHOW;
251         mmsHeader.deliveryReport = (MmsReport)MMS_REPORT_NO;
252         mmsHeader.readReply = (MmsReport)MMS_REPORT_NO;
253         mmsHeader.reportAllowed = (MmsReportAllowed)MMS_REPORTALLOWED_YES;
254         memset(mmsHeader.szContentLocation, 0, MMS_LOCATION_LEN + 1);
255
256
257         mmsHeader.msgStatus = (msg_delivery_report_status_t)MSG_DELIVERY_REPORT_NONE;
258         mmsHeader.readStatus = (msg_read_report_status_t)MSG_READ_REPORT_NONE;
259
260         mmsHeader.replyCharge.chargeType = (MmsReplyChargeType)MMS_REPLY_NONE;
261         mmsHeader.replyCharge.chargeSize = 0;
262         mmsHeader.replyCharge.deadLine.type = MMS_TIMETYPE_RELATIVE;
263         mmsHeader.replyCharge.deadLine.time = 0;
264         memset(mmsHeader.replyCharge.szChargeID, 0, MMS_MSG_ID_LEN + 1);
265
266
267         memset(mmsHeader.szMsgID, 0, MMS_MSG_ID_LEN + 1);
268         mmsHeader.msgSize = 0;
269 #ifdef __SUPPORT_DRM__
270         mmsHeader.drmType = MSG_DRM_TYPE_NONE;
271 #endif
272
273         __MmsDecodeInitialize();
274 }
275
276 void MmsReleaseHeader(MmsHeader *mms)
277 {
278         __MsgFreeHeaderAddress(mms->pFrom);
279         __MsgFreeHeaderAddress(mms->pTo);
280         __MsgFreeHeaderAddress(mms->pCc);
281         __MsgFreeHeaderAddress(mms->pBcc);
282
283         mmsHeader.pFrom = NULL;
284         mmsHeader.pTo = NULL;
285         mmsHeader.pCc = NULL;
286         mmsHeader.pBcc = NULL;
287
288 }
289
290 static void __MmsCleanDecodeBuff(void)
291 {
292         memset(gpMmsDecodeBuf1, 0, gMmsDecodeMaxLen + 1);
293         memset(gpMmsDecodeBuf2, 0, gMmsDecodeMaxLen + 1);
294         gpCurMmsDecodeBuff = NULL;
295         gCurMmsDecodeBuffPos = 0;
296         gMmsDecodeBufLen = 0;
297 }
298
299 void MmsRegisterDecodeBuffer()
300 {
301         gpMmsDecodeBuf1 = gszMmsLoadBuf1;
302         gpMmsDecodeBuf2 = gszMmsLoadBuf2;
303         gpCurMmsDecodeBuff = NULL;
304         gCurMmsDecodeBuffPos = 0;
305         gMmsDecodeMaxLen = MSG_MMS_DECODE_BUFFER_MAX;
306         gMmsDecodeCurOffset = 0;
307         gMmsDecodeBufLen = 0;
308 }
309
310 void MmsUnregisterDecodeBuffer(void)
311 {
312         gpMmsDecodeBuf1 = NULL;
313         gpMmsDecodeBuf2 = NULL;
314         gpCurMmsDecodeBuff = NULL;
315         gCurMmsDecodeBuffPos = 0;
316         gMmsDecodeMaxLen = 0;
317         gMmsDecodeCurOffset = 0;
318         gMmsDecodeBufLen = 0;
319 }
320
321
322 static int __MmsGetDecodeOffset(void)
323 {
324         return (gMmsDecodeCurOffset - gMmsDecodeBufLen + gCurMmsDecodeBuffPos);
325 }
326
327 static bool __MmsBinaryDecodeCheckAndDecreaseLength(int *pLength, int valueLength)
328 {
329         if (*pLength <= valueLength) {
330                 gCurMmsDecodeBuffPos -= valueLength;
331                 gCurMmsDecodeBuffPos += *pLength;
332                 return false;
333         }
334
335         *pLength -= valueLength;
336
337         return true;
338 }
339
340
341 /* ==========================================================
342
343            B  I  N  A  R  Y         D  E  C  O  D  I  N  G
344
345    ==========================================================*/
346
347 /*
348  * Binary Encoded Message Format
349  *
350  *              < Single Part Body Message >
351  * -----------------------------------
352  * |            Header Fields                    |
353  * -----------------------------------
354  * | Content Type:start=xxx;type=xxx |  ->(ex) Text/Plain, Text/Html, ....
355  * -----------------------------------
356  * |            Single Part Body                 |
357  * -----------------------------------
358  *
359  *              < Multi Part Body Message >
360  * -----------------------------------
361  * |            Header Fields                    |
362  * -----------------------------------
363  * | Content Type:start=xxx;type=xxx |  -> (ex) Application/vnd.wap.multipart.mixed(related), multipart/mixed(related)
364  * -----------------------------------
365  * |    # of Entries (body parts)        |
366  * -----------------------------------                          < Each Entry >
367  * |                    Entry 1                          |      ->      -----------------------------
368  * -----------------------------------          |               header Length           |
369  * |                    Entry 2                          |              -----------------------------
370  * -----------------------------------          |               Data Length                     |
371  * |                    ......                           |              -----------------------------  -
372  * -----------------------------------          |               Content-Type            |  |
373  * |                    Entry n                          |              -----------------------------  | Header Length
374  * -----------------------------------          |                       Header                  |  |
375  *                                                                                      -----------------------------  -
376  *                                                                                      |                       Data                    |  | Data Length
377  *                                                                                      -----------------------------  -
378  */
379 bool MmsBinaryDecodeMsgHeader(FILE *pFile, int totalLength)
380 {
381         UINT16 fieldCode = 0xffff;
382         UINT16 fieldValue = 0xffff;
383         UINT8 oneByte = 0xff;
384
385         MsgHeaderAddress *pAddr = NULL;
386         MsgHeaderAddress *pLastTo = NULL;
387         MsgHeaderAddress *pLastCc = NULL;
388         MsgHeaderAddress *pLastBcc = NULL;
389
390         UINT32 valueLength = 0;
391         UINT32 tmpInteger = 0;
392         int     tmpIntLen = 0;
393
394         int offset = 0;
395
396         char szGarbageBuff[MSG_STDSTR_LONG]     = {0, };
397         char *pLimitData = NULL;
398         int nRead = 0;
399
400         MSG_DEBUG("pFile=%d, total len=%d\n", pFile, totalLength);
401
402         __MmsCleanDecodeBuff();
403
404         if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos,
405                                                                    &gMmsDecodeCurOffset, gpMmsDecodeBuf1, gpMmsDecodeBuf2,
406                                                                    gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
407                 MSG_DEBUG("fail to load to buffer \n");
408                 goto __CATCH;
409         }
410
411         while (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength)) {
412                 fieldCode = oneByte & 0x7f;
413
414                 switch (MmsGetBinaryType(MmsCodeFieldCode, fieldCode)) {
415                 case MMS_CODE_RESPONSESTATUS:
416
417                         if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
418                                 MSG_DEBUG("responseStatus GetOneByte fail\n");
419                                 goto __CATCH;
420                         }
421
422                         // range 197 to 223 as it does to the value 192 (Error-transient-failure).
423                         // range 236 to 255 as it does to the value 224 (Error-permanent-failure).
424                         if (fieldValue >= 0x0045 && fieldValue <= 0x005F) {
425                                 fieldValue = 0x0040;
426                         } else if (fieldValue >= 0x006A && fieldValue <= 0x007F) {
427                                 fieldValue = 0x0060;
428                         }
429
430                         MSG_DEBUG("response status code = 0x%02x", oneByte);
431
432                         fieldValue = MmsGetBinaryType(MmsCodeResponseStatus, (UINT16)(oneByte & 0x7F));
433
434                         if (fieldValue == 0xFFFF) {
435                                 MSG_DEBUG("responseStatus error\n");
436                                 goto __CATCH;
437                         }
438
439                         mmsHeader.responseStatus = (MmsResponseStatus)fieldValue;
440
441                         MSG_DEBUG("response status text = %s\n", MmsDebugGetResponseStatus(mmsHeader.responseStatus));
442
443                         break;
444
445                 case MMS_CODE_RETRIEVESTATUS:
446
447                         if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
448                                 MSG_DEBUG("retrieveStatus GetOneByte fail\n");
449                                 goto __CATCH;
450                         }
451
452                         MSG_DEBUG("retrieve status code = 0x%02x", oneByte);
453
454                         fieldValue = MmsGetBinaryType(MmsCodeRetrieveStatus, (UINT16)(oneByte & 0x7F));
455
456                         if (fieldValue == 0xFFFF) {
457                                 MSG_DEBUG("retrieveStatus error\n");
458                                 goto __CATCH;
459                         }
460
461                         if (fieldValue >= 0x0043 && fieldValue <= 0x005F) {
462                                 fieldValue = 0x0040; // 192; Error-transient-failure
463                         } else if (fieldValue >= 0x0064 && fieldValue <= 0x007F) {
464                                 fieldValue = 0x0060; //224; Error-permanent-failure
465                         }
466
467                         mmsHeader.retrieveStatus = (MmsRetrieveStatus)fieldValue;
468
469                         MSG_DEBUG("retrieve status = %s\n", MmsDebugGetRetrieveStatus(mmsHeader.retrieveStatus));
470
471                         break;
472
473                 case MMS_CODE_RESPONSETEXT:
474
475                         if (__MmsBinaryDecodeEncodedString(pFile, mmsHeader.szResponseText, MMS_LOCALE_RESP_TEXT_LEN + 1, totalLength) == false) {
476                                 MSG_DEBUG("invalid MMS_CODE_RESPONSETEXT \n");
477                                 goto __CATCH;
478                         }
479
480                         MSG_DEBUG("response text = %s\n", mmsHeader.szResponseText);
481                         break;
482
483                 case MMS_CODE_RETRIEVETEXT:
484
485                         if (__MmsBinaryDecodeEncodedString(pFile, mmsHeader.szRetrieveText, MMS_LOCALE_RESP_TEXT_LEN + 1, totalLength) == false) {
486                                 MSG_DEBUG("invalid MMS_CODE_RETRIEVETEXT \n");
487                                 goto __CATCH;
488                         }
489
490                         MSG_DEBUG("retrieve text = %s\n", mmsHeader.szRetrieveText);
491                         break;
492
493                 case MMS_CODE_MSGID:
494
495                         if (__MmsBinaryDecodeText(pFile, mmsHeader.szMsgID, MMS_MSG_ID_LEN + 1, totalLength) < 0) {
496                                 MSG_DEBUG("MMS_CODE_MSGID is invalid\n");
497                                 goto __CATCH;
498                         }
499
500                         MSG_DEBUG("msg id = %s\n", mmsHeader.szMsgID);
501
502                         if (MsgStrlen (mmsHeader.szMsgID) > 2)
503                                 __MsgMIMERemoveQuote (mmsHeader.szMsgID);
504
505                         break;
506
507                 case MMS_CODE_SUBJECT:
508
509                         if (__MmsBinaryDecodeEncodedString(pFile, mmsHeader.szSubject, MSG_LOCALE_SUBJ_LEN + 1, totalLength) == false) {
510                                 MSG_DEBUG("invalid MMS_CODE_SUBJECT \n");
511                                 goto __CATCH;
512                         }
513
514                         pLimitData = (char *)malloc(MSG_LOCALE_SUBJ_LEN + 1);
515
516                         if (pLimitData == NULL) {
517                                 MSG_DEBUG("pLimitData malloc fail \n");
518                                 goto __CATCH;
519                         }
520
521                         nRead = __MsgCutUTFString((unsigned char*)pLimitData, MSG_LOCALE_SUBJ_LEN + 1, (unsigned char*)mmsHeader.szSubject, MSG_SUBJ_LEN);
522                         MSG_DEBUG("Subject edit.. \n");
523
524                         if (nRead > MSG_LOCALE_SUBJ_LEN) {
525                                 memset(mmsHeader.szSubject, 0 , sizeof(mmsHeader.szSubject));
526                                 strncpy(mmsHeader.szSubject, pLimitData, MSG_SUBJ_LEN);
527                         } else {
528                                 memset(mmsHeader.szSubject, 0 , sizeof(mmsHeader.szSubject));
529                                 strncpy(mmsHeader.szSubject, pLimitData, MSG_LOCALE_SUBJ_LEN);
530                         }
531
532                         if (pLimitData) {
533                                 free(pLimitData);
534                                 pLimitData = NULL;
535                         }
536
537                         MSG_DEBUG("subject = %s\n", mmsHeader.szSubject);
538                         break;
539
540                 case MMS_CODE_FROM:
541
542                         /* Value-length (Address-present-token Encoded-string-value | Insert-address-token) */
543
544                         if (__MmsDecodeValueLength(pFile, &valueLength, totalLength) <= 0) {
545                                 MSG_DEBUG("MMS_CODE_FROM is invalid\n");
546                                 goto __CATCH;
547                         }
548
549                         if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
550                                 MSG_DEBUG("MMS_CODE_FROM GetOneByte fail\n");
551                                 goto __CATCH;
552                         }
553
554                         // DRM_TEMPLATE - start
555
556                         valueLength--;
557
558                         if (oneByte == (MmsGetBinaryValue(MmsCodeAddressType, MMS_ADDRESS_PRESENT_TOKEN)|0x80)) {
559                                 if (valueLength > 0) {
560                                         mmsHeader.pFrom = __MmsDecodeEncodedAddress(pFile, totalLength);
561                                         if (mmsHeader.pFrom == NULL) {
562                                                 MSG_DEBUG("MMS_CODE_FROM __MmsDecodeEncodedAddress fail\n");
563                                                 goto __CATCH;
564                                         }
565                                 } else {
566                                         mmsHeader.pFrom = (MsgHeaderAddress *)malloc(sizeof(MsgHeaderAddress));
567                                         if (mmsHeader.pFrom == NULL)
568                                                 goto __CATCH;
569
570                                         mmsHeader.pFrom->szAddr = (char *)malloc(1);
571                                         if (mmsHeader.pFrom->szAddr == NULL) {
572                                                 free(mmsHeader.pFrom);
573                                                 mmsHeader.pFrom = NULL;
574                                                 goto __CATCH;
575                                         }
576
577                                         mmsHeader.pFrom->szAddr[0] = '\0';
578                                         mmsHeader.pFrom->pNext = NULL;
579                                 }
580
581                                 MSG_DEBUG("from = %s\n", mmsHeader.pFrom->szAddr);
582                                 // DRM_TEMPLATE - end
583                         } else if (oneByte == (MmsGetBinaryValue(MmsCodeAddressType, MMS_INSERT_ADDRESS_TOKEN)|0x80)) {
584                                 /* Present Token only */
585                                 MSG_DEBUG("MMS_CODE_FROM insert token\n");
586                         } else {
587                                 /* from data broken */
588                                 MSG_DEBUG("from addr broken\n");
589                                 gCurMmsDecodeBuffPos--;
590                                 goto __CATCH;
591                         }
592                         break;
593
594                 case MMS_CODE_TO:
595
596                         pAddr = __MmsDecodeEncodedAddress(pFile, totalLength);
597                         if (pAddr == NULL) {
598                                 MSG_DEBUG("MMS_CODE_TO __MmsDecodeEncodedAddress fail\n");
599                                 goto __CATCH;
600                         }
601
602                         if (mmsHeader.pTo == NULL) {
603                                 /* the first TO */
604                                 pLastTo = mmsHeader.pTo = pAddr;
605                         } else {
606                                 if (pLastTo)
607                                         pLastTo->pNext = pAddr;
608                                 pLastTo = pAddr;
609                         }
610
611                         MSG_DEBUG("to = %s\n", mmsHeader.pTo->szAddr);
612                         break;
613
614                 case MMS_CODE_BCC:
615
616                         pAddr = __MmsDecodeEncodedAddress(pFile, totalLength);
617                         if (pAddr == NULL) {
618                                 MSG_DEBUG("MMS_CODE_BCC __MmsDecodeEncodedAddress fail\n");
619                                 goto __CATCH;
620                         }
621
622                         if (mmsHeader.pBcc == NULL) {
623                                 /* the first Bcc */
624                                 pLastBcc = mmsHeader.pBcc = pAddr;
625                         } else {
626                                 if (pLastBcc)
627                                         pLastBcc->pNext = pAddr;
628                                 pLastBcc = pAddr;
629                         }
630
631                         MSG_DEBUG("bcc = %s\n", mmsHeader.pBcc->szAddr);
632                         break;
633
634                 case MMS_CODE_CC:
635
636                         pAddr = __MmsDecodeEncodedAddress(pFile, totalLength);
637                         if (pAddr == NULL) {
638                                 MSG_DEBUG("MMS_CODE_CC __MmsDecodeEncodedAddress fail\n");
639                                 goto __CATCH;
640                         }
641
642                         if (mmsHeader.pCc == NULL) {
643                                 /* the first Cc */
644                                 pLastCc = mmsHeader.pCc = pAddr;
645                         } else {
646                                 if (pLastCc)
647                                         pLastCc->pNext = pAddr;
648                                 pLastCc = pAddr;
649                         }
650                         MSG_DEBUG("cc = %s\n", mmsHeader.pCc->szAddr);
651                         break;
652
653                 case MMS_CODE_CONTENTLOCATION:
654
655                         if (__MmsBinaryDecodeText(pFile, mmsHeader.szContentLocation, MMS_LOCATION_LEN + 1, totalLength) < 0) {
656                                 MSG_DEBUG("MMS_CODE_CONTENTLOCATION is invalid\n");
657                                 goto __CATCH;
658                         }
659                         MSG_DEBUG("content location = %s\n", mmsHeader.szContentLocation);
660                         break;
661
662                 case MMS_CODE_DATE:
663
664                         if (__MmsDecodeLongInteger(pFile, (UINT32*)&mmsHeader.date, totalLength) == false) {
665                                 MSG_DEBUG("MMS_CODE_DATE is invalid\n");
666                                 goto __CATCH;
667                         }
668                         MSG_DEBUG("date = %d\n", mmsHeader.date);
669                         break;
670
671                 case MMS_CODE_DELIVERYREPORT:
672
673                         if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
674                                 MSG_DEBUG("deliveryReport GetOneByte fail\n");
675                                 goto __CATCH;
676                         }
677
678                         fieldValue = MmsGetBinaryType(MmsCodeDeliveryReport, (UINT16)(oneByte & 0x7F));
679
680                         if (fieldValue == 0xFFFF) {
681                                 MSG_DEBUG("deliveryReport error\n");
682                                 goto __CATCH;
683                         }
684
685                         mmsHeader.deliveryReport = (MmsReport)fieldValue;
686
687                         MSG_DEBUG("delivery report=%s\n", MmsDebugGetMmsReport(mmsHeader.deliveryReport));
688                         break;
689
690                 case MMS_CODE_DELIVERYTIME:
691
692                         /* value_length (absolute-token Long-integer | Relative-token Long-integer) */
693
694                         if (__MmsDecodeValueLength(pFile, &valueLength, totalLength) <= 0) {
695                                 MSG_DEBUG("invalid MMS_CODE_DELIVERYTIME \n");
696                                 goto __CATCH;
697                         }
698
699                         if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
700                                 MSG_DEBUG("delivery time GetOneByte fail\n");
701                                 goto __CATCH;
702                         }
703
704                         //DRM_TEMPLATE - start
705                         valueLength--;
706
707                         if (oneByte == (MmsGetBinaryValue(MmsCodeTimeType, MMS_TIMETYPE_ABSOLUTE)|0x80)) {
708                                 mmsHeader.deliveryTime.type = MMS_TIMETYPE_ABSOLUTE;
709
710                                 if (valueLength > 0) {
711                                         if (__MmsDecodeLongInteger(pFile, (UINT32*)&mmsHeader.deliveryTime.time, totalLength) == false) {
712                                                 MSG_DEBUG("invalid MMS_CODE_DELIVERYTIME\n");
713                                                 goto __CATCH;
714                                         }
715                                 }
716                         // DRM_TEMPLATE - end
717                         } else {
718                                 mmsHeader.deliveryTime.type = MMS_TIMETYPE_RELATIVE;
719
720                                 if (__MmsBinaryDecodeInteger(pFile, (UINT32*)&mmsHeader.deliveryTime.time, &tmpIntLen, totalLength) == false) {
721                                         MSG_DEBUG("__MmsBinaryDecodeInteger fail...\n");
722                                         goto __CATCH;
723                                 }
724                         }
725                         MSG_DEBUG("delivery type=%d, time=%d\n", mmsHeader.deliveryTime.type, mmsHeader.deliveryTime.time);
726                         break;
727
728                 case MMS_CODE_EXPIRYTIME:
729
730                         /* value_length(absolute-token Long-integer | Relative-token Long-integer) */
731
732                         if (__MmsDecodeValueLength(pFile, &valueLength, totalLength) <= 0) {
733                                 MSG_DEBUG("invalid MMS_CODE_EXPIRYTIME \n");
734                                 goto __CATCH;
735                         }
736
737                         if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
738                                 MSG_DEBUG("expiry time GetOneByte fail\n");
739                                 goto __CATCH;
740                         }
741
742                         // DRM_TEMPLATE - start
743                         valueLength--;
744
745                         if (oneByte == (MmsGetBinaryValue(MmsCodeTimeType, MMS_TIMETYPE_ABSOLUTE)|0x80)) {
746                                 mmsHeader.expiryTime.type = MMS_TIMETYPE_ABSOLUTE;
747
748                                 if (valueLength > 0) {
749                                         if (__MmsDecodeLongInteger(pFile, (UINT32*)&mmsHeader.expiryTime.time, totalLength) == false) {
750                                                 MSG_DEBUG("MMS_CODE_EXPIRYTIME is invalid\n");
751                                                 goto __CATCH;
752                                         }
753                                 }
754                         // DRM_TEMPLATE - end
755                         } else {
756                                 mmsHeader.expiryTime.type = MMS_TIMETYPE_RELATIVE;
757
758                                 if (__MmsBinaryDecodeInteger(pFile, (UINT32*)&mmsHeader.expiryTime.time, &tmpIntLen, totalLength) == false) {
759                                         MSG_DEBUG("__MmsBinaryDecodeInteger fail...\n");
760                                         goto __CATCH;
761                                 }
762                         }
763                         MSG_DEBUG("expiry = %d\n", mmsHeader.expiryTime.time);
764                         break;
765
766                 case MMS_CODE_MSGCLASS:
767
768                         /* Class-value = Class-identifier | Token Text */
769
770                         if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
771                                 MSG_DEBUG("msgClass GetOneByte fail\n");
772                                 goto __CATCH;
773                         }
774
775                         if (oneByte > 0x7f) {
776                                 /* Class-identifier */
777                                 mmsHeader.msgClass = (MmsMsgClass)MmsGetBinaryType(MmsCodeMsgClass, (UINT16)(oneByte & 0x7F));
778                         } else {
779                                 if (__MmsBinaryDecodeText(pFile, szGarbageBuff, MSG_STDSTR_LONG, totalLength) < 0) {
780                                         MSG_DEBUG("1. __MmsBinaryDecodeText fail. (class)\n");
781                                         goto __CATCH;
782                                 }
783                         }
784                         MSG_DEBUG("msg class=%s\n", MmsDebugGetMsgClass(mmsHeader.msgClass));
785                         break;
786
787                 case MMS_CODE_MSGSIZE:
788
789                         if (__MmsDecodeLongInteger(pFile, (UINT32*)&mmsHeader.msgSize, totalLength) == false) {
790                                 MSG_DEBUG("MMS_CODE_MSGSIZE is invalid\n");
791                                 goto __CATCH;
792                         }
793                         MSG_DEBUG("msg size = %d\n", mmsHeader.msgSize);
794                         break;
795
796                 case MMS_CODE_MSGSTATUS:
797
798                         if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
799                                 MSG_DEBUG("msgStatus GetOneByte fail\n");
800                                 goto __CATCH;
801                         }
802
803                         mmsHeader.msgStatus =  (msg_delivery_report_status_t)MmsGetBinaryType(MmsCodeMsgStatus, (UINT16)(oneByte & 0x7F));
804                         MSG_DEBUG("msg status=%s \n", MmsDebugGetMsgStatus(mmsHeader.msgStatus)) ;
805                         break;
806
807                 case MMS_CODE_MSGTYPE:
808
809                         if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
810                                 MSG_DEBUG("msgStatus GetOneByte fail\n");
811                                 goto __CATCH;
812                         }
813
814                         mmsHeader.type = (MmsMsgType)MmsGetBinaryType(MmsCodeMsgType, (UINT16)(oneByte & 0x7F));
815                         MSG_DEBUG("msg type=%s\n", MmsDebugGetMsgType(mmsHeader.type));
816                         break;
817
818                 case MMS_CODE_PRIORITY:
819
820                         if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
821                                 MSG_DEBUG("msgStatus GetOneByte fail\n");
822                                 goto __CATCH;
823                         }
824                         mmsHeader.priority = (MmsPriority)MmsGetBinaryType(MmsCodePriority, (UINT16)(oneByte & 0x7F));
825                         MSG_DEBUG("priority=%d\n", mmsHeader.priority);
826                         break;
827
828                 case MMS_CODE_READREPLY:
829
830                         if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
831                                 MSG_DEBUG("msgStatus GetOneByte fail\n");
832                                 goto __CATCH;
833                         }
834                         mmsHeader.readReply = (MmsReport)MmsGetBinaryType(MmsCodeReadReply, (UINT16)(oneByte & 0x7F));
835                         MSG_DEBUG("read reply=%s \n", MmsDebugGetMmsReport(mmsHeader.readReply));
836                         break;
837
838                 case MMS_CODE_REPORTALLOWED:
839
840                         if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
841                                 MSG_DEBUG("msgStatus GetOneByte fail\n");
842                                 goto __CATCH;
843                         }
844                         mmsHeader.reportAllowed =  (MmsReportAllowed)MmsGetBinaryType(MmsCodeReportAllowed, (UINT16)(oneByte & 0x7F));
845                         MSG_DEBUG("mmsHeader.reportAllowed=%d\n", MmsDebugGetMmsReportAllowed(mmsHeader.reportAllowed));
846                         break;
847
848                 case MMS_CODE_SENDERVISIBILLITY:
849
850                         if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
851                                 MSG_DEBUG("msgStatus GetOneByte fail\n");
852                                 goto __CATCH;
853                         }
854                         mmsHeader.hideAddress= (MmsSenderVisible)!(MmsGetBinaryType(MmsCodeSenderVisibility, (UINT16)(oneByte &0x7F)));
855                         MSG_DEBUG("sender visible=%d \n", mmsHeader.hideAddress);
856                         break;
857
858                 case MMS_CODE_TRID:
859
860                         if (__MmsBinaryDecodeText(pFile, mmsHeader.szTrID, MMS_TR_ID_LEN + 1, totalLength) < 0) {
861                                 MSG_DEBUG("Transaction ID Too Long \n");
862                                 goto __CATCH;
863                         }
864                         MSG_DEBUG("trID = %s\n", mmsHeader.szTrID);
865                         break;
866
867                 case MMS_CODE_VERSION:
868                         if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
869                                 MSG_DEBUG("msgStatus GetOneByte fail\n");
870                                 goto __CATCH;
871                         }
872                         mmsHeader.version = oneByte;
873
874                         MSG_DEBUG("ver = 0x%x\n", mmsHeader.version);
875                         break;
876
877                 case MMS_CODE_CONTENTTYPE:
878
879                         /*
880                          * Content-type is the last header field of SendRequest and RetrieveConf.
881                          * It's required to decrease pointer by one and return,
882                          * to parse this field in MmsBinaryDecodeContentType().
883                          */
884                         goto __RETURN;
885
886
887                 /* ----------- Add by MMSENC v1.1 ----------- */
888
889                 case MMS_CODE_READSTATUS:
890
891                         /* Read-status-value = Read | Deleted without being read */
892
893                         if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
894                                 MSG_DEBUG("msgStatus GetOneByte fail\n");
895                                 goto __CATCH;
896                         }
897
898                         mmsHeader.readStatus =  (msg_read_report_status_t)MmsGetBinaryType(MmsCodeReadStatus, (UINT16)(oneByte & 0x7F));
899                         MSG_DEBUG("read status=%s\n", MmsDebugGetMmsReadStatus(mmsHeader.readStatus));
900                         break;
901
902                 case MMS_CODE_REPLYCHARGING:
903
904                         /* Reply-charging-value = Requested | Requested text only | Accepted | Accepted text only */
905
906                         if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
907                                 MSG_DEBUG("msgStatus GetOneByte fail\n");
908                                 goto __CATCH;
909                         }
910
911                         mmsHeader.replyCharge.chargeType =  (MmsReplyChargeType)MmsGetBinaryType(MmsCodeReplyCharging, (UINT16)(oneByte & 0x7F));
912                         MSG_DEBUG("mmsHeader.reply charge=%d\n", mmsHeader.replyCharge.chargeType);
913                         break;
914
915                 case MMS_CODE_REPLYCHARGINGDEADLINE:
916
917                         /* Reply-charging-deadline-value = Value-length (Absolute-token Date-value | Relative-token Delta-seconds-value) */
918
919                         if (__MmsDecodeValueLength(pFile, &valueLength, totalLength) <= 0) {
920                                 MSG_DEBUG("invalid MMS_CODE_REPLYCHARGINGDEADLINE \n");
921                                 goto __CATCH;
922                         }
923
924                         if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
925                                 MSG_DEBUG("msgStatus GetOneByte fail\n");
926                                 goto __CATCH;
927                         }
928
929                         if (oneByte == (MmsGetBinaryValue(MmsCodeTimeType, MMS_TIMETYPE_ABSOLUTE) | 0x80)) {
930                                 mmsHeader.replyCharge.deadLine.type = MMS_TIMETYPE_ABSOLUTE;
931                         } else {
932                                 mmsHeader.replyCharge.deadLine.type = MMS_TIMETYPE_RELATIVE;
933                         }
934
935                         // DRM_TEMPLATE - start
936                         valueLength--;
937
938                         if (valueLength > 0) {
939                                 if (__MmsDecodeLongInteger(pFile, (UINT32*)&mmsHeader.replyCharge.deadLine.time, totalLength) == false) {
940                                         MSG_DEBUG("MMS_CODE_REPLYCHARGINGDEADLINE is invalid\n");
941                                         goto __CATCH;
942                                 }
943                         }
944                         // DRM_TEMPLATE - end
945                         break;
946
947                 case MMS_CODE_REPLYCHARGINGID:
948
949                         /* Reply-charging-ID-value = Text-string */
950
951                         if (__MmsBinaryDecodeText(pFile, mmsHeader.replyCharge.szChargeID, MMS_MSG_ID_LEN + 1, totalLength) < 0) {
952                                 MSG_DEBUG("1. __MmsBinaryDecodeText fail. (szReplyChargingID)\n");
953                                 goto __CATCH;
954                         }
955                         break;
956
957                 case MMS_CODE_REPLYCHARGINGSIZE:
958
959                         /* Reply-charging-size-value = Long-integer */
960
961                         if (__MmsDecodeLongInteger(pFile, (UINT32*)&mmsHeader.replyCharge.chargeSize, totalLength) == false) {
962                                 MSG_DEBUG("MMS_CODE_REPLYCHARGINGSIZE is invalid\n");
963                                 goto __CATCH;
964                         }
965                         break;
966
967                 case MMS_CODE_PREVIOUSLYSENTBY:
968
969                         /*
970                          * Previously-sent-by-value = Value-length Forwarded-count-value Encoded-string-value
971                          * Forwarded-count-value = Integer-value
972                          * MMS_CODE_PREVIOUSLYSENTBY shall be a pair with MMS_CODE_PREVIOUSLYSENTDATE
973                          */
974
975                         /*
976                          * fixme: There is no proper field to store this information.
977                          * Just increase pointer now.
978                          */
979
980                         if (__MmsDecodeValueLength(pFile, &valueLength, totalLength) <= 0) {
981                                 MSG_DEBUG("1. invalid MMS_CODE_PREVIOUSLYSENTBY \n");
982                                 goto __CATCH;
983                         }
984
985                         if (__MmsBinaryDecodeInteger(pFile, &tmpInteger, &tmpIntLen, totalLength) == false) {
986                                 MSG_DEBUG("2. invalid MMS_CODE_PREVIOUSLYSENTBY \n");
987                                 goto __CATCH;
988                         }
989
990                         if (__MmsBinaryDecodeEncodedString(pFile, szGarbageBuff, MSG_STDSTR_LONG, totalLength) == false) {
991                                 MSG_DEBUG("invalid MMS_CODE_RETRIEVETEXT \n");
992                                 goto __CATCH;
993                         }
994                         break;
995
996                 case MMS_CODE_PREVIOUSLYSENTDATE:
997
998                         /*
999                          * Previously-sent-date-value = Value-length Forwarded-count-value Date-value
1000                          * Forwarded-count-value = Integer-value
1001                          * MMS_CODE_PREVIOUSLYSENTDATE shall be a pair with MMS_CODE_PREVIOUSLYSENTBY
1002                          */
1003
1004                         /*
1005                          * fixme: There is no proper field to store this information.
1006                          * Just increase pointer now.
1007                          */
1008
1009                         if (__MmsDecodeValueLength(pFile, &valueLength, totalLength) <= 0) {
1010                                 MSG_DEBUG("1. invalid MMS_CODE_PREVIOUSLYSENTDATE \n");
1011                                 goto __CATCH;
1012                         }
1013
1014                         if (__MmsBinaryDecodeInteger(pFile, &tmpInteger, &tmpIntLen, totalLength) == false) {
1015                                 MSG_DEBUG("2. invalid MS_CODE_PREVIOUSLYSENTDATE \n");
1016                                 goto __CATCH;
1017                         }
1018
1019                         if (__MmsDecodeLongInteger(pFile, (UINT32*)&tmpInteger, totalLength) == false) {
1020                                 MSG_DEBUG("3. invalid MMS_CODE_PREVIOUSLYSENTDATE \n");
1021                                 goto __CATCH;
1022                         }
1023                         break;
1024
1025                 default:
1026
1027                         /*
1028                          * Application-header             = Token-text Application-specific-value
1029                          * Token-text                             = Token End-of-string
1030                          * Application-specific-value = Text -string
1031                          *
1032                          * OR unknown header field - Just ignore these fields.
1033                          *
1034                          * Read one byte and check the value >= 0x80
1035                          * (check these value can be field code)
1036                          */
1037                         {
1038                                 int             remainLength = 0;
1039
1040                                 oneByte = 0x00;
1041
1042                                 offset = __MmsGetDecodeOffset();
1043                                 if (offset >= totalLength)
1044                                         goto __RETURN;
1045
1046                                 remainLength = totalLength - offset;
1047
1048                                 while ((oneByte < 0x80) && (remainLength > 0)) {
1049                                         if (__MmsBinaryDecodeCheckAndDecreaseLength(&remainLength, 1) == false) {
1050                                                 MSG_DEBUG("__MmsBinaryDecodeCheckAndDecreaseLength fail\n");
1051                                                 goto __CATCH;
1052                                         }
1053                                         if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
1054                                                 MSG_DEBUG("responseStatus GetOneByte fail\n");
1055                                                 goto __CATCH;
1056                                         }
1057                                 }
1058
1059                                 gCurMmsDecodeBuffPos--;
1060                         }
1061
1062                         break;
1063                 }       /* switch */
1064
1065                 offset = __MmsGetDecodeOffset();
1066                 if (offset >= totalLength)
1067                         goto __RETURN;
1068
1069         }       /* while */
1070
1071
1072 __RETURN:
1073
1074         if (mmsHeader.pTo == NULL && pLastTo) {
1075                 free(pLastTo);
1076         }
1077
1078         if (mmsHeader.pCc == NULL && pLastCc) {
1079                 free(pLastCc);
1080         }
1081
1082         if (mmsHeader.pBcc == NULL && pLastBcc) {
1083                 free(pLastBcc);
1084         }
1085
1086         MSG_DEBUG("success\n");
1087         return true;
1088
1089
1090 __CATCH:
1091
1092         if (mmsHeader.pTo == NULL && pLastTo) {
1093                 free(pLastTo);
1094         }
1095
1096         if (mmsHeader.pCc == NULL && pLastCc) {
1097                 free(pLastCc);
1098         }
1099
1100         if (mmsHeader.pBcc == NULL && pLastBcc) {
1101                 free(pLastBcc);
1102         }
1103
1104         MSG_DEBUG("failed\n");
1105
1106         return false;
1107 }
1108
1109 bool MmsBinaryDecodeMsgBody(FILE *pFile, char *szFilePath, int totalLength)
1110 {
1111         MSG_BEGIN();
1112
1113         int length = 0;
1114         int offset = 0;
1115
1116         if (szFilePath != NULL)
1117                 strncpy(mmsHeader.msgType.szOrgFilePath, szFilePath , strlen(szFilePath));
1118
1119         mmsHeader.msgType.offset = __MmsGetDecodeOffset() - 1;          // + Content-Type code value
1120
1121         // read data(2K) from msg file(/User/Msg/Inbox/5) to gpCurMmsDecodeBuff for decoding
1122         if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos,
1123                                                                         &gMmsDecodeCurOffset, gpMmsDecodeBuf1, gpMmsDecodeBuf2,
1124                                                                         gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
1125                 MSG_DEBUG("fail to load to buffer \n");
1126                 goto __CATCH;
1127         }
1128
1129         // msg's type [ex] related, mixed, single part (jpg, amr and etc)
1130         length = __MmsBinaryDecodeContentType(pFile, &mmsHeader.msgType, totalLength);
1131         if (length == -1) {
1132                 MSG_DEBUG("MMS_CODE_CONTENTTYPE is fail\n");
1133                 goto __CATCH;
1134         }
1135
1136         mmsHeader.msgType.size   = length + 1; // + Content-Type code value
1137         mmsHeader.msgBody.offset = __MmsGetDecodeOffset();
1138
1139         switch (mmsHeader.msgType.type) {
1140         case MIME_APPLICATION_VND_WAP_MULTIPART_MIXED:
1141         case MIME_APPLICATION_VND_WAP_MULTIPART_RELATED:
1142         case MIME_APPLICATION_VND_WAP_MULTIPART_ASTERIC:
1143         case MIME_APPLICATION_VND_WAP_MULTIPART_ALTERNATIVE:
1144         case MIME_MULTIPART_REPORT:
1145         case MIME_MULTIPART_MIXED:
1146         case MIME_MULTIPART_RELATED:
1147         case MIME_MULTIPART_ALTERNATIVE:
1148         case MIME_APPLICATION_VND_OMA_DRM_MESSAGE:
1149         case MIME_APPLICATION_VND_OMA_DRM_CONTENT:
1150
1151                 MSG_DEBUG("Decode multipart\n");
1152
1153                 offset = __MmsGetDecodeOffset();
1154                 if (offset >= totalLength)
1155                         goto __RETURN;
1156
1157                 if (__MmsBinaryDecodeMultipart(pFile, szFilePath, &mmsHeader.msgType, &mmsHeader.msgBody, totalLength) == false) {
1158                         MSG_DEBUG("MmsBinaryDecodeMultipart is fail.\n");
1159                         goto __CATCH;
1160                 }
1161                 break;
1162
1163         default:
1164
1165                 /* Single part message ---------------------------------------------- */
1166                 if (szFilePath != NULL)
1167                         strcpy(mmsHeader.msgBody.szOrgFilePath, szFilePath);
1168
1169                 offset = __MmsGetDecodeOffset();
1170                 if (offset >= totalLength)
1171                         goto __RETURN;
1172
1173                 if (__MmsBinaryDecodePartBody(pFile, totalLength - mmsHeader.msgBody.offset, totalLength) == false) {
1174                         MSG_DEBUG("MmsBinaryDecodePartBody is fail.(Single Part)\n");
1175                         goto __CATCH;
1176                 }
1177
1178                 mmsHeader.msgBody.size = totalLength - mmsHeader.msgBody.offset;
1179                 mmsHeader.msgType.contentSize = totalLength - mmsHeader.msgBody.offset;
1180
1181                 break;
1182         }
1183
1184 #ifdef __SUPPORT_DRM__
1185         mmsHeader.drmType = MsgGetDRMType(&mmsHeader.msgType, &mmsHeader.msgBody);
1186 #endif
1187
1188 __RETURN:
1189         MSG_END();
1190         return true;
1191
1192 __CATCH:
1193         return false;
1194 }
1195
1196 static bool __MmsBinaryDecodeParameter(FILE *pFile, MsgType *pMsgType, int valueLength, int totalLength)
1197 {
1198         UINT8 oneByte = 0;
1199         int charSetLen = 0;
1200         char *szTypeString = NULL;
1201         char *szTypeValue = NULL;
1202         UINT8 paramCode = 0xff;
1203         UINT32 integer = 0;
1204         int intLen = 0;
1205         int length = 0;
1206         int textLength = 0;
1207
1208         /*
1209          * Parameter = Typed-parameter | Untyped-parameter
1210          * WAP-230-WSP-20010118-p, Proposed Version 18 January 2001 (pp.107)
1211          */
1212
1213         MSG_BEGIN();
1214
1215         while (valueLength > 0) {
1216                 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
1217                         MSG_DEBUG("paramCode _MmsBinaryDecodeGetOneByte fail\n");
1218                         goto __CATCH;
1219                 }
1220
1221                 paramCode = oneByte;
1222                 valueLength--;
1223
1224                 switch (paramCode) {
1225                 case 0x81: // charset
1226
1227                         if (__MmsBinaryDecodeCharset(pFile, (UINT32*)&(pMsgType->param.charset), &charSetLen, totalLength) == false) {
1228                                 MSG_DEBUG("MmsBinaryDecodeContentType : __MmsBinaryDecodeCharset fail.\n");
1229                                 goto __CATCH;
1230                         }
1231
1232                         if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, charSetLen) == false)
1233                                 goto __RETURN;
1234
1235                         break;
1236
1237                 case 0x85: //name = Text-string
1238                 case 0x97: //name = Text-value  = No-value | Token-text | Quoted-string
1239                         memset(pMsgType->param.szName, 0, sizeof(pMsgType->param.szName));
1240                         length = __MmsDecodeGetFilename(pFile,  pMsgType->param.szName,
1241                                                                                          MSG_FILENAME_LEN_MAX -5,               // MSG_LOCALE_FILENAME_LEN_MAX + 1, :  change @ 110(Ui code have to change for this instead of DM)
1242                                                                                          totalLength);
1243                         if (length < 0) {
1244                                 MSG_DEBUG("MmsBinaryDecodeContentType : __MmsDecodeGetFilename fail. (name parameter)\n");
1245                                 goto __CATCH;
1246                         }
1247
1248                         if (__MsgCheckFileNameHasInvalidChar(pMsgType->param.szName)) {
1249                                 __MsgReplaceInvalidFileNameChar(pMsgType->param.szName, '_');
1250                         }
1251
1252                         if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, length) == false)
1253                                 goto __RETURN;
1254
1255                         break;
1256
1257                 case 0x86: //filename = Text-string
1258                 case 0x98: //filename = Text-value  = No-value | Token-text | Quoted-string
1259                         memset(pMsgType->param.szFileName, 0, sizeof(pMsgType->param.szFileName));
1260                         length = __MmsDecodeGetFilename(pFile, pMsgType->param.szFileName, MSG_FILENAME_LEN_MAX -5, totalLength);
1261                         if (length < 0) {
1262                                 MSG_DEBUG("MmsBinaryDecodeContentType : __MmsDecodeGetFilename fail. (filename parameter)\n");
1263                                 goto __CATCH;
1264                         }
1265
1266                         if (__MsgCheckFileNameHasInvalidChar(pMsgType->param.szFileName)) {
1267                                 __MsgReplaceInvalidFileNameChar(pMsgType->param.szFileName, '_');
1268                         }
1269
1270                         if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, length) == false)
1271                                 goto __RETURN;
1272
1273                         break;
1274
1275                 case 0x89: //type = Constrained-encoding = Extension-Media | Short-integer
1276
1277                         if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
1278                                 MSG_DEBUG("type _MmsBinaryDecodeGetOneByte fail\n");
1279                                 goto __CATCH;
1280                         }
1281
1282                         if (oneByte > 0x7f) {
1283                                 pMsgType->param.type = MmsGetBinaryType(MmsCodeContentType,
1284                                                                                                                   (UINT16)(oneByte & 0x7f));
1285                                 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, 1) == false)
1286                                         goto __RETURN;
1287                         } else {
1288                                 gCurMmsDecodeBuffPos--;
1289
1290                                 textLength = 0;
1291                                 szTypeString = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1292                                 pMsgType->param.type = MmsGetTextType(MmsCodeContentType, szTypeString);
1293
1294                                 if (szTypeString) {
1295                                         free(szTypeString);
1296                                         szTypeString = NULL;
1297                                 }
1298
1299                                 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, textLength) == false)
1300                                         goto __RETURN;
1301                         }
1302
1303                         break;
1304
1305                 case 0x8A: //start encoding version 1.2
1306                 case 0x99: //start encoding version 1.4
1307
1308                         textLength       = 0;
1309                         szTypeString = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1310                         if (szTypeString) {
1311                                 memset(pMsgType->param.szStart, 0, MMS_CONTENT_ID_LEN + 1);
1312                                 strncpy(pMsgType->param.szStart, szTypeString, MMS_CONTENT_ID_LEN);
1313                                 free(szTypeString);
1314                                 szTypeString = NULL;
1315
1316                                 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, textLength) == false)
1317                                         goto __RETURN;
1318                         }
1319
1320                         break;
1321
1322                 case 0x8B: //startInfo encoding version 1.2
1323                 case 0x9A: //startInfo encoding version 1.4
1324
1325                         textLength       = 0;
1326                         szTypeString = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1327
1328                         if (szTypeString) {
1329                                 memset(pMsgType->param.szStartInfo, 0, MMS_CONTENT_ID_LEN + 1);
1330                                 strncpy(pMsgType->param.szStartInfo, szTypeString, MMS_CONTENT_ID_LEN);
1331
1332                                 free(szTypeString);
1333                                 szTypeString = NULL;
1334
1335                                 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, textLength) == false)
1336                                         goto __RETURN;
1337                         }
1338
1339                         break;
1340
1341                 default:
1342
1343                         if (paramCode > 0x7F) {
1344                                 MSG_DEBUG("Unsupported parameter\n");
1345
1346                                 // In case of the last byte of Parameter field, it should be returned without decreasing the gCurMmsDecodeBuffPos value.
1347                                 valueLength++;
1348                                 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, 1) == false)
1349                                         goto __RETURN;
1350                         } else {
1351                                 /*
1352                                  * Untyped Parameter = Token-text Untyped-value
1353                                  * Token-text            = Token End-of-string
1354                                  * Untyped-value         = Integer-value | Text-value
1355                                  * Text-value            = No-value | Token-text | Quoted-string
1356                                  *
1357                                  * Just increase pointer!!!
1358                                  */
1359
1360
1361                                 /* Token-text */
1362
1363                                 gCurMmsDecodeBuffPos--;
1364                                 valueLength++;
1365
1366                                 textLength        = 0;
1367                                 szTypeString  = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1368                                 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, textLength) == false)
1369                                         goto __RETURN;
1370
1371
1372                                 /* Text-value */
1373
1374                                 if (__MmsBinaryDecodeInteger(pFile, &integer, &intLen, totalLength) == true) {
1375                                         MSG_DEBUG("Unsupported parameter(%d)\n", integer);
1376                                         if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, intLen) == false)
1377                                                 goto __RETURN;
1378                                 } else {
1379                                         textLength        = 0;
1380                                         szTypeValue  = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1381
1382                                         if (szTypeValue) {
1383                                                 /* checkMe:  forwardLock needs boudary string */
1384                                                 if (strcasecmp(szTypeString, "boundary") == 0) {
1385                                                         memset(pMsgType->param.szBoundary, 0, MSG_BOUNDARY_LEN + 1);
1386                                                         strncpy(pMsgType->param.szBoundary, szTypeValue, MSG_BOUNDARY_LEN);
1387 #ifdef FEATURE_JAVA_MMS
1388                                                 } else if (strcasecmp(szTypeString, "Application-ID") == 0) {
1389                                                         pMsgType->param.szApplicationID = (char*) malloc(textLength + 1);
1390                                                         memset(pMsgType->param.szApplicationID,  0,  textLength + 1);
1391                                                         strncpy(pMsgType->param.szApplicationID, szTypeValue, textLength);
1392                                                         MSG_DEBUG("Application-ID:%s",pMsgType->param.szApplicationID);
1393                                                 } else if (strcasecmp(szTypeString,"Reply-To-Application-ID") == 0) {
1394                                                         pMsgType->param.szReplyToApplicationID= (char*) malloc(textLength + 1);
1395                                                         memset(pMsgType->param.szReplyToApplicationID, 0, textLength + 1);
1396                                                         strncpy(pMsgType->param.szReplyToApplicationID, szTypeValue, textLength);
1397                                                         MSG_DEBUG("ReplyToApplication-ID:%s",pMsgType->param.szReplyToApplicationID);
1398 #endif
1399                                                 }
1400                                                 free(szTypeValue);
1401                                                 szTypeValue = NULL;
1402
1403                                                 MSG_DEBUG("Unsupported parameter(%s)\n", szTypeValue);
1404                                                 if (__MmsBinaryDecodeCheckAndDecreaseLength(&valueLength, textLength) == false)
1405                                                         goto __RETURN;
1406                                         }
1407                                 }
1408
1409                                 if (szTypeString) {
1410                                         MSG_DEBUG("Unsupported parameter(%s)\n", szTypeString);
1411                                         free(szTypeString);
1412                                         szTypeString = NULL;
1413                                 }
1414                         }
1415
1416                         break;
1417                 }
1418         }       /*end of while loop*/
1419
1420
1421 __RETURN:
1422
1423         if (szTypeString) {
1424                 free(szTypeString);
1425                 szTypeString = NULL;
1426         }
1427
1428         return true;
1429
1430 __CATCH:
1431
1432         return false;
1433 }
1434
1435 /**
1436  * Decode Encoded Content type
1437  *
1438  * @param       pEncodedData    [in] ContentType encoded data
1439  * @param       pMsgType                [out] Decoded MsgType
1440  * @return      Decoded address list
1441  */
1442 static int __MmsBinaryDecodeContentType(FILE *pFile, MsgType *pMsgType, int totalLength)
1443 {
1444         UINT8 oneByte = 0;
1445         char *szTypeString = NULL;
1446         int valueLength = 0;
1447         int length = 0;
1448         int textLength = 0;
1449
1450
1451         /*
1452          * Content-type-value             : [WAPWSP 8.4.2.24]
1453          * Preassigned content-types  : [WAPWSP Appendix A, Table 40]
1454          * The use of start-parameter : [RFC2387] and SHOULD be encoded according to [WAPWSP].
1455          *
1456          * Content-type-value   = Constrained-media | Content-general-form
1457          * Content-general-form = Value-length Media-type
1458          * Media-type                   = (Well-known-media | Extension-Media) *(Parameter)
1459          */
1460
1461         MSG_DEBUG("decoding content type..\n");
1462
1463         length = __MmsDecodeValueLength(pFile, (UINT32*)&valueLength, totalLength);
1464         if (length <= 0) {
1465                 /*
1466                  * Constrained-media or Single part message
1467                  * Constrained-media = Constrained-encoding = Extension-Media | Short-integer
1468                  * Extension-media   = *TEXT End-of-string
1469                  * Short-integer     = OCTET(1xxx xxxx)
1470                  */
1471
1472                 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
1473                         MSG_DEBUG("Constrained-media _MmsBinaryDecodeGetOneByte fail\n");
1474                         goto __CATCH;
1475                 }
1476
1477                 if (oneByte > 0x7F) {
1478                         /* Short-integer */
1479                         pMsgType->type = MmsGetBinaryType(MmsCodeContentType, (UINT16)(oneByte & 0x7F));
1480                         length = 1;
1481                 } else {
1482                         char *pszTemp = NULL;
1483
1484                         /* Extension-Media */
1485                         gCurMmsDecodeBuffPos--;
1486
1487                         textLength = 0;
1488                         szTypeString = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1489
1490                         if (szTypeString && (strchr(szTypeString, ';')) != NULL) {
1491                                 pszTemp = __MsgGetStringUntilDelimiter(szTypeString, ';');
1492                                 if (pszTemp) {
1493                                         free(szTypeString);
1494                                         szTypeString = pszTemp;
1495                                 }
1496                         }
1497
1498                         pMsgType->type = MmsGetTextType(MmsCodeContentType, szTypeString);
1499
1500                         length = textLength;
1501
1502                         if (szTypeString) {
1503                                 free(szTypeString);
1504                                 szTypeString = NULL;
1505                         }
1506                 }
1507         } else {
1508                 /*
1509                  * Content-general-form = Value-length Media-type
1510                  * Media-type                   = (Well-known-media | Extension-Media)*(Parameter)
1511                  */
1512
1513                 length += valueLength;
1514
1515                 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
1516                         MSG_DEBUG("Well-known-media _MmsBinaryDecodeGetOneByte fail\n");
1517                         goto __CATCH;
1518                 }
1519
1520                 if (oneByte > 0x7F) {
1521                         /* Well-known-media */
1522                         pMsgType->type = MmsGetBinaryType(MmsCodeContentType, (UINT16)(oneByte & 0x7F));
1523                         valueLength--;
1524                 } else {
1525                         /* Extension-Media */
1526                         gCurMmsDecodeBuffPos--;
1527
1528                         textLength = 0;
1529                         szTypeString = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1530                         pMsgType->type = MmsGetTextType(MmsCodeContentType, szTypeString);
1531                         valueLength -= textLength;
1532
1533                         if (szTypeString) {
1534                                 free(szTypeString);
1535                                 szTypeString = NULL;
1536                         }
1537                 }
1538
1539                 MSG_DEBUG("content type=%s\n", MmsDebugGetMimeType((MimeType)pMsgType->type));
1540
1541
1542                 if (__MmsBinaryDecodeParameter(pFile, pMsgType, valueLength, totalLength) == false) {
1543                         MSG_DEBUG("Content-Type parameter fail\n");
1544                         goto __CATCH;
1545                 }
1546         }
1547
1548         return length;
1549
1550 __CATCH:
1551         return -1;
1552 }
1553
1554 static bool __MmsBinaryDecodePartHeader(FILE *pFile, MsgType *pMsgType, int headerLen, int totalLength)
1555 {
1556         UINT8 fieldCode = 0xff;
1557         int length = 0;
1558         UINT32 valueLength = 0;
1559         char *pCode = NULL;
1560         char *pValue = NULL;
1561         char *pParam = NULL;
1562         char ch = '\0';
1563         UINT8 oneByte = 0;
1564         int     textLength = 0;
1565         int tmpInt = 0;
1566         int tmpIntLen = 0;
1567         char *pLatinBuff = NULL;
1568         char *szSrc = NULL;
1569         char *szTemp = NULL;
1570
1571
1572         if (pFile == NULL || pMsgType == NULL)
1573                 return false;
1574
1575         /*
1576          * Message-header                         = Well-known-header | Application-header
1577          * Well-known-header              = Well-known-field-name Wap-value
1578          * Application-header             = Token-text Application-specific-value
1579          * Well-known-field-name          = Short-integer
1580          * Application-specific-value = Text-string
1581          */
1582
1583         while (headerLen > 0) {
1584                 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
1585                         MSG_DEBUG("field code GetOneByte fail\n");
1586                         goto __CATCH;
1587                 }
1588
1589                 if (0x80 <= oneByte && oneByte <= 0xC7) {
1590                         /* Well-known-header = Well-known-field-name Wap-value (0x00 ~ 0x47) */
1591
1592                         if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, 1) == false)
1593                                 goto __RETURN;
1594
1595                         fieldCode = oneByte & 0x7f;
1596
1597                         switch (fieldCode) {
1598                         case 0x0E:      //Content-Location
1599                         case 0x04:      //Content-Location
1600
1601                                 pLatinBuff = (char *)malloc(MMS_CONTENT_ID_LEN + 1);
1602                                 if (pLatinBuff == NULL)
1603                                         goto __CATCH;
1604
1605                                 length = __MmsBinaryDecodeText(pFile, pLatinBuff, MMS_CONTENT_ID_LEN + 1, totalLength);
1606                                 if (length == -1) {
1607                                         MSG_DEBUG("MmsBinaryDecodePartHeader : __MmsBinaryDecodeQuotedString fail.\n");
1608                                         goto __CATCH;
1609                                 }
1610
1611                                 szSrc = MsgChangeHexString(pLatinBuff);
1612
1613                                 if (szSrc) {
1614                                         strcpy(pLatinBuff, szSrc);
1615                                         free(szSrc);
1616                                         szSrc = NULL;
1617                                 }
1618
1619                                 textLength = strlen(pLatinBuff);
1620
1621                                 if (__MsgLatin2UTF ((unsigned char*)pMsgType->szContentLocation, MMS_CONTENT_ID_LEN + 1, (unsigned char*)pLatinBuff, textLength) < 0) {
1622                                         MSG_DEBUG("MsgLatin2UTF fail \n");
1623                                         goto __CATCH;
1624                                 }
1625
1626                                 free(pLatinBuff);
1627                                 pLatinBuff = NULL;
1628
1629                                 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, length) == false)
1630                                         goto __RETURN;
1631
1632                                 break;
1633
1634                         case 0x40:      // Content-ID
1635                         {
1636                                 char szContentID[MMS_CONTENT_ID_LEN + 1];
1637
1638                                 pLatinBuff = (char *)malloc(MMS_CONTENT_ID_LEN + 1);
1639                                 if (pLatinBuff == NULL)
1640                                         goto __CATCH;
1641
1642                                 length = __MmsBinaryDecodeQuotedString(pFile, pLatinBuff, MMS_CONTENT_ID_LEN + 1, totalLength);
1643
1644                                 if (length == -1) {
1645                                         MSG_DEBUG("MmsBinaryDecodePartHeader : Content-ID __MmsBinaryDecodeQuotedString fail.\n");
1646                                         goto __CATCH;
1647                                 }
1648
1649                                 szSrc = MsgChangeHexString(pLatinBuff);
1650
1651                                 if (szSrc) {
1652                                         strcpy(pLatinBuff, szSrc);
1653                                         free(szSrc);
1654                                         szSrc = NULL;
1655                                 }
1656
1657                                 textLength = strlen(pLatinBuff);
1658                                 if (__MsgLatin2UTF ((unsigned char*)szContentID, MMS_CONTENT_ID_LEN + 1, (unsigned char*)pLatinBuff, textLength) < 0) {
1659                                         MSG_DEBUG("MsgLatin2UTF fail \n");
1660                                         goto __CATCH;
1661                                 }
1662                                 free(pLatinBuff);
1663                                 pLatinBuff = NULL;
1664
1665                                 removeLessGreaterMark(szContentID, pMsgType->szContentID, sizeof(pMsgType->szContentID));//remove "< >"
1666
1667                                 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, length) == false)
1668                                         goto __RETURN;
1669                         }
1670                                 break;
1671
1672                         case 0x2E:      // Content-Disposition
1673                         case 0x45:      // Content-Disposition
1674
1675                                 /*
1676                                  * Content-disposition-value = Value-length Disposition *(Parameter)
1677                                  * Disposition = Form-data | Attachment | Inline | Token-text
1678                                  *                               Form-data = <Octet 128> : 0x80
1679                                  *                               Attachment = <Octet 129> : 0x81
1680                                  *                               Inline = <Octet 130> : 0x82
1681                                  */
1682
1683                                 length = __MmsDecodeValueLength2(pFile, &valueLength, totalLength);
1684
1685                                 if (length > 0) {
1686                                         if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, length) == false)
1687                                                 goto __RETURN;
1688
1689                                 }
1690
1691                                 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
1692                                         MSG_DEBUG("Disposition value GetOneByte fail\n");
1693                                         goto __CATCH;
1694                                 }
1695
1696                                 if (length > 0)
1697                                         valueLength--;
1698
1699                                 if (oneByte >= 0x80) {
1700                                         pMsgType->disposition = MmsGetBinaryType(MmsCodeMsgDisposition, (UINT16)(oneByte & 0x7F));
1701
1702                                         if (pMsgType->disposition == INVALID_HOBJ) {
1703                                                 MSG_DEBUG("MmsBinaryDecodePartHeader : Content-Disposition MmsGetBinaryType fail.\n");
1704                                                 pMsgType->disposition = MSG_DISPOSITION_ATTACHMENT;             // default
1705                                         }
1706
1707                                         if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, 1) == false)
1708                                                 goto __RETURN;
1709
1710                                         if (__MmsBinaryDecodeParameter(pFile, pMsgType, valueLength, totalLength) == false) {
1711                                                 MSG_DEBUG("Disposition parameter fail\n");
1712                                                 goto __CATCH;
1713                                         }
1714
1715                                         if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, valueLength) == false)
1716                                                 goto __RETURN;
1717                                 } else {
1718
1719                                         gCurMmsDecodeBuffPos--;
1720                                         valueLength++;
1721
1722                                         pLatinBuff = (char *)malloc(MSG_FILENAME_LEN_MAX);
1723                                         memset(pLatinBuff, 0, MSG_FILENAME_LEN_MAX);
1724
1725                                         textLength = __MmsBinaryDecodeText(pFile, pLatinBuff, MSG_FILENAME_LEN_MAX-1, totalLength);
1726
1727
1728                                         if (textLength < 0) {
1729                                                 MSG_DEBUG("MmsBinaryDecodePartHeader : Content-Disposition decodingfail. \n");
1730                                                 goto __CATCH;
1731                                         }
1732                                         free(pLatinBuff);
1733                                         pLatinBuff = NULL;
1734
1735                                         if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, textLength) == false)
1736                                                 goto __RETURN;
1737
1738                                         valueLength -= textLength;
1739
1740                                         if (__MmsBinaryDecodeParameter(pFile, pMsgType, valueLength, totalLength) == false)
1741                                         {
1742                                                 MSG_DEBUG("Disposition parameter fail\n");
1743                                                 goto __CATCH;
1744                                         }
1745
1746                                         if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, valueLength) == false)
1747                                                 goto __RETURN;
1748
1749                                 }
1750
1751                                 break;
1752
1753                         case 0x0B:      //Content-Encoding
1754
1755                                 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
1756                                         MSG_DEBUG("Disposition value GetOneByte fail\n");
1757                                         goto __CATCH;
1758                                 }
1759
1760                                 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, 1) == false)
1761                                         goto __RETURN;
1762
1763                                 break;
1764
1765                         case 0x0C:      //Content-Language
1766
1767                                 if (__MmsBinaryDecodeInteger(pFile, (UINT32*)&tmpInt, &tmpIntLen, totalLength) == true) {
1768                                         if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, tmpIntLen) == false)
1769                                                 goto __RETURN;
1770                                 } else {
1771                                         char* cTemp = NULL;
1772
1773                                         cTemp = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1774
1775                                         if (cTemp == NULL) {
1776                                                 MSG_DEBUG("MmsBinaryDecodePartHeader : __MmsBinaryDecodeText2 fail...\n");
1777                                                 goto __CATCH;
1778                                         }
1779
1780                                         if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, textLength) == false) {
1781                                                 if (cTemp) {
1782                                                         free(cTemp);
1783                                                 }
1784                                                 goto __RETURN;
1785                                         }
1786
1787                                         if (cTemp)
1788                                                 free(cTemp);
1789                                 }
1790
1791                                 break;
1792
1793                         case 0x0D:      //Content-Length
1794
1795                                 if (__MmsBinaryDecodeInteger(pFile, (UINT32*)&tmpInt, &tmpIntLen, totalLength) == false) {
1796                                         MSG_DEBUG("MmsBinaryDecodePartHeader : __MmsBinaryDecodeInteger fail...\n");
1797                                         goto __CATCH;
1798                                 }
1799
1800                                 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, tmpIntLen) == false)
1801                                         goto __RETURN;
1802
1803                                 break;
1804
1805                         case 0x30:      //X-Wap-Content-URI skip this value
1806
1807                                 MSG_DEBUG("MmsBinaryDecodePartHeader : X-Wap-Content-URI header.\n");
1808                                 pLatinBuff = (char *)malloc(MMS_TEXT_LEN);
1809                                 if (pLatinBuff == NULL)
1810                                         goto __CATCH;
1811
1812                                 length = __MmsBinaryDecodeText(pFile, pLatinBuff, MMS_TEXT_LEN, totalLength);
1813
1814                                 if (length == -1) {
1815                                         MSG_DEBUG("MmsBinaryDecodePartHeader : __MmsBinaryDecodeQuotedString fail.\n");
1816                                         goto __CATCH;
1817                                 }
1818
1819                                 MSG_DEBUG("MmsBinaryDecodePartHeader : X-Wap-Content-URI header decoded. Value length %d\n", length);
1820                                 free(pLatinBuff);
1821                                 pLatinBuff = NULL;
1822
1823                                 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, length) == false)
1824                                         goto __RETURN;
1825
1826                                 MSG_DEBUG("MmsBinaryDecodePartHeader : X-Wap-Content-URI header skipped.\n");
1827
1828                                 break;
1829
1830                         case 0x01:      // Accept-charset
1831                                 //if (NvGetInt(NV_SI_ADM_GCF_STATE) == 1)
1832                                 {
1833                                         /*      WAP-230-WSP-200010705-a.pdf
1834                                                 8.4.2.8 Accept charset field
1835                                                 The following rules are used to encode accept character set values.
1836                                                 Accept-charset-value = Constrained-charset | Accept-charset-general-form
1837                                                 Accept-charset-general-form = Value-length (Well-known-charset | Token-text) [Q-value]
1838                                                 Constrained-charset = Any-charset | Constrained-encoding
1839                                                 Well-known-charset = Any-charset | Integer-value
1840                                                 ; Both are encoded using values from Character Set Assignments table in Assigned Numbers
1841                                                 Any-charset = <Octet 128>
1842                                                 ; Equivalent to the special RFC2616 charset value ï¿½ï¿½*��
1843                                         */
1844
1845                                         int     charset = 0;
1846                                         int charSetLen = 0;
1847
1848                                         MSG_DEBUG("MmsBinaryDecodePartHeader : Accept-charset. \n");
1849
1850                                         length = __MmsDecodeValueLength(pFile, &valueLength, totalLength);
1851                                         if (length > 0) {
1852                                                 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, length) == false)
1853                                                         goto __RETURN;
1854
1855                                         }
1856
1857                                         if (__MmsBinaryDecodeInteger(pFile, (UINT32*)&charset, &charSetLen, totalLength) == false) {
1858                                                 // We only support the well-known-charset format
1859                                                 MSG_DEBUG("MmsBinaryDecodePartHeader : __MmsBinaryDecodeInteger fail...\n");
1860                                                 goto __CATCH;
1861                                         }
1862
1863                                         if (charset > 0)
1864                                                 MmsGetBinaryType(MmsCodeCharSet, (UINT16)charset);
1865
1866                                         if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, charSetLen) == false)
1867                                                 goto __RETURN;
1868
1869                                         break;
1870                                 }
1871
1872                         default:
1873
1874                                 /* Other Content-xxx headers : Have valueLength */
1875
1876                                 MSG_DEBUG("MmsBinaryDecodePartHeader : unknown Value = 0x%x\n", oneByte);
1877
1878                                 length = __MmsDecodeValueLength(pFile, &valueLength, totalLength);
1879                                 if (length <= 0) {
1880                                         MSG_DEBUG("MmsBinaryDecodePartHeader : 1. invalid MMS_CODE_PREVIOUSLYSENTDATE \n");
1881                                         goto __CATCH;
1882                                 }
1883
1884                                 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, length) == false)
1885                                         goto __RETURN;
1886
1887                                 szTemp = (char *)malloc(valueLength);
1888                                 if (szTemp == NULL)
1889                                         goto __CATCH;
1890
1891                                 if (__MmsBinaryDecodeGetBytes(pFile, szTemp, valueLength, totalLength) == false) {
1892                                         MSG_DEBUG("MmsBinaryDecodePartHeader : default _MmsBinaryDecodeGetBytes() fail\n");
1893                                         if (szTemp) {
1894                                                 free(szTemp);
1895                                                 szTemp = NULL;
1896                                         }
1897                                         goto __CATCH;
1898                                 }
1899
1900                                 if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, valueLength) == false)
1901                                         goto __RETURN;
1902
1903                                 break;
1904                         }
1905                 } else {
1906                         /*
1907                          * Application-header  = Token-text Application-specific-value
1908                          * Application-specific-value = Text-string
1909                          */
1910
1911                         MSG_DEBUG(" Application-header = Token-text Application-specific-value \n");
1912
1913                         gCurMmsDecodeBuffPos--;
1914
1915                         /* Token-text */
1916
1917                         textLength = 0;
1918                         pCode = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1919                         if (pCode == NULL) {
1920                                 MSG_DEBUG("pCode is null\n");
1921                                 goto __CATCH;
1922                         }
1923
1924                         if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, textLength) == false)
1925                                 goto __RETURN;
1926
1927                         MSG_DEBUG(" Token-text (%s) \n", pCode);
1928
1929
1930                         /* Application-specific-value */
1931
1932                         textLength = 0;
1933                         pValue = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
1934                         if (pValue == NULL) {
1935                                 MSG_DEBUG("pValue is null\n");
1936                                 goto __CATCH;
1937                         }
1938
1939                         MSG_DEBUG(" Application-specific-value (%s) \n", pValue);
1940
1941
1942                         pParam = strchr(pValue, MSG_CH_ADDR_DELIMETER);
1943                         if (pParam) {
1944                                 ch = *pParam;
1945                                 *pParam = '\0';
1946                         }
1947
1948                         switch (MmsGetTextType(MmsCodeMsgBodyHeaderCode, pCode)) {
1949                         case MMS_BODYHDR_TRANSFERENCODING:              // Content-Transfer-Encoding
1950                                 pMsgType->encoding = MmsGetTextType(MmsCodeContentTransferEncoding, pValue);
1951                                 break;
1952
1953                         case MMS_BODYHDR_CONTENTID:                             // Content-ID
1954                         {
1955                                 char szContentID[MMS_CONTENT_ID_LEN + 1];
1956
1957                                 pLatinBuff = (char *)malloc(MMS_CONTENT_ID_LEN + 1);
1958                                 if (pLatinBuff == NULL)
1959                                 {
1960                                         goto __CATCH;
1961                                 }
1962
1963                                 __MsgMIMERemoveQuote (pValue);
1964                                 strncpy(pLatinBuff, pValue, MMS_MSG_ID_LEN);
1965
1966                                 length = strlen(pLatinBuff);
1967                                 if (__MsgLatin2UTF ((unsigned char*)szContentID, MMS_CONTENT_ID_LEN + 1, (unsigned char*)pLatinBuff, length) < 0)
1968                                 {
1969                                         MSG_DEBUG("MsgLatin2UTF fail \n");
1970                                         goto __CATCH;
1971                                 }
1972
1973                                 removeLessGreaterMark(szContentID, pMsgType->szContentID, sizeof(pMsgType->szContentID));//remove "< >"
1974
1975                                 free(pLatinBuff);
1976                                 pLatinBuff = NULL;
1977                                 break;
1978                         }
1979                         case MMS_BODYHDR_CONTENTLOCATION:               // Content-Location
1980
1981                                 pLatinBuff = (char *)malloc(MMS_CONTENT_ID_LEN + 1);
1982                                 if (pLatinBuff == NULL)
1983                                         goto __CATCH;
1984
1985                                 strncpy(pLatinBuff, pValue, MMS_MSG_ID_LEN);
1986
1987                                 length = strlen(pLatinBuff);
1988                                 if (__MsgLatin2UTF ((unsigned char*)pMsgType->szContentLocation, MMS_CONTENT_ID_LEN + 1, (unsigned char*)pLatinBuff, length) < 0) {
1989                                         MSG_DEBUG("MsgLatin2UTF fail \n");
1990                                         goto __CATCH;
1991                                 }
1992
1993                                 free(pLatinBuff);
1994                                 pLatinBuff = NULL;
1995                                 break;
1996
1997                         case MMS_BODYHDR_DISPOSITION:                   // Content-Disposition
1998                                 pMsgType->disposition = MmsGetTextType(MmsCodeMsgDisposition, pValue);
1999                                 break;
2000
2001                         case MMS_BODYHDR_X_OMA_DRM_SEPARATE_DELIVERY:   // DRM RO WAITING
2002                                         break;
2003
2004                         default:
2005                                 MSG_DEBUG("Unknown Field : %s, Value: %s\n", pCode, pValue);
2006                                 break;
2007                         }
2008
2009                         if (pParam) {
2010                                 __MsgParseParameter(pMsgType, pParam + 1);
2011                                 *pParam = ch;
2012                         }
2013                         if (pCode) {
2014                                 free(pCode);
2015                                 pCode = NULL;
2016                         }
2017                         if (pValue) {
2018                                 free(pValue);
2019                                 pValue = NULL;
2020                         }
2021
2022                         if (__MmsBinaryDecodeCheckAndDecreaseLength(&headerLen, textLength) == false)
2023                                 goto __RETURN;
2024
2025                 }
2026         }       //while
2027
2028 __RETURN:
2029 /* DEADCODE
2030         if (pLatinBuff) {
2031                 free(pLatinBuff);
2032                 pLatinBuff = NULL;
2033         }
2034 */
2035         if (szTemp) {
2036                 free(szTemp);
2037                 szTemp = NULL;
2038         }
2039
2040         if (pCode) {
2041                 free(pCode);
2042                 pCode = NULL;
2043         }
2044
2045         return true;
2046
2047 __CATCH:
2048
2049         if (pLatinBuff) {
2050                 free(pLatinBuff);
2051                 pLatinBuff = NULL;
2052         }
2053         if (pCode) {
2054                 free(pCode);
2055                 pCode = NULL;
2056         }
2057         if (pValue) {
2058                 free(pValue);
2059                 pValue = NULL;
2060         }
2061
2062         if (szTemp) {
2063                 free(szTemp);
2064                 szTemp = NULL;
2065         }
2066
2067         return false;
2068 }
2069
2070 static bool __MmsBinaryDecodeEntries(FILE *pFile, UINT32 *npEntries, int totalLength)
2071 {
2072         int length = 0;
2073
2074         length = __MmsBinaryDecodeUintvar(pFile, npEntries, totalLength);
2075         if (length <= 0) {
2076                 goto __CATCH;
2077         }
2078
2079         MSG_DEBUG("Number of Entries = %d\n", *npEntries);
2080
2081         return true;
2082
2083 __CATCH:
2084         return false;
2085 }
2086
2087 static bool __MmsBinaryDecodePartBody(FILE *pFile, UINT32 bodyLength, int totalLength)
2088 {
2089         int offset = 0;
2090
2091         /*
2092          * Currently, offset and size is
2093          * the only information used with msgBody.
2094          * If you need, add here more information
2095          */
2096         MSG_BEGIN();
2097
2098         offset = __MmsGetDecodeOffset();
2099         offset += bodyLength;
2100
2101         if (MsgFseek(pFile, offset, SEEK_SET) < 0) {
2102                 MSG_DEBUG("fail to seek file pointer \n");
2103                 goto __CATCH;
2104         }
2105
2106         __MmsCleanDecodeBuff();
2107
2108         gMmsDecodeCurOffset = offset;
2109
2110         if (offset >= totalLength)
2111                 goto __RETURN;
2112
2113         if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
2114                                                                    gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
2115                 MSG_DEBUG("fail to load to buffer \n");
2116                 goto __CATCH;
2117         }
2118
2119         return true;
2120
2121 __RETURN:
2122         return true;
2123
2124 __CATCH:
2125         return false;
2126 }
2127
2128 static bool __MmsBinaryDecodeMovePointer(FILE *pFile, int offset, int totalLength)
2129 {
2130         if (offset > totalLength)
2131                 goto __RETURN;
2132
2133         if (MsgFseek(pFile, offset, SEEK_SET) < 0) {
2134                 MSG_DEBUG("fail to seek file pointer \n");
2135                 goto __CATCH;
2136         }
2137
2138         __MmsCleanDecodeBuff();
2139
2140         gMmsDecodeCurOffset = offset;
2141
2142         if (offset == totalLength)
2143                 goto __RETURN;
2144
2145         if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
2146                                                                         gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
2147                 MSG_DEBUG("fail to load to buffer \n");
2148                 goto __CATCH;
2149         }
2150
2151 __RETURN:
2152         return true;
2153
2154 __CATCH:
2155         return false;
2156 }
2157
2158 static bool __MmsBinaryDecodeMultipart(FILE *pFile, char *szFilePath, MsgType *pMsgType, MsgBody *pMsgBody, int totalLength)
2159 {
2160         UINT32 nEntries = 0;
2161         MsgMultipart *pMultipart = NULL;
2162         MsgMultipart *pLastMultipart = NULL;
2163         MsgMultipart *pPreMultipart     = NULL;
2164         int offset = 0;
2165         int     index = 0;
2166
2167         MsgPresentationFactor factor = MSG_PRESENTATION_NONE;
2168         MsgPresentaionInfo presentationInfo;
2169
2170         MSG_DEBUG("total length=%d\n", totalLength);
2171
2172         presentationInfo.factor = MSG_PRESENTATION_NONE;
2173         presentationInfo.pCurPresentation = NULL;
2174         presentationInfo.pPrevPart = NULL;
2175
2176         if (__MmsBinaryDecodeEntries(pFile, &nEntries, totalLength) == false) {
2177                 MSG_DEBUG("MmsBinaryDecodeEntries is fail.\n");
2178                 goto __CATCH;
2179         }
2180
2181         if (pMsgBody->body.pMultipart != NULL) {
2182                 pLastMultipart = pMsgBody->body.pMultipart;
2183                 MSG_DEBUG("pMsgBody->body.pMultipart exist \n");
2184         } else {
2185                 MSG_DEBUG("pMsgBody->body.pMultipart == NULL\n");
2186         }
2187
2188         while (nEntries) {
2189                 MSG_DEBUG("decoding %dth multipart\n", index);
2190
2191                 offset = __MmsGetDecodeOffset();
2192                 if (offset >= totalLength)
2193                         goto __RETURN;
2194
2195                 if ((pMultipart = __MsgAllocMultipart()) == NULL) {
2196                         MSG_DEBUG("MsgAllocMultipart Fail \n");
2197                         goto __CATCH;
2198                 }
2199
2200                 if (__MmsBinaryDecodeEachPart(pFile, szFilePath, &(pMultipart->type), pMultipart->pBody, totalLength) == false) {
2201                         MSG_DEBUG("MmsBinaryDecodeEachPart is fail.(nEntries = %d)\n", nEntries);
2202                         goto __CATCH;
2203                 }
2204
2205                 if (pMsgType->param.type == MIME_APPLICATION_SMIL) {
2206                         factor = __MsgIsPresentationEx(&(pMultipart->type), pMsgType->param.szStart, (MimeType)pMsgType->param.type);
2207                 } else {
2208                         factor = MSG_PRESENTATION_NONE;
2209                 }
2210                 // priority 1 : content type match, 2: content location, 3: type
2211                 if (presentationInfo.factor < factor) {
2212                         // Presentation part
2213                         presentationInfo.factor = factor;
2214                         presentationInfo.pPrevPart = pPreMultipart;
2215                         presentationInfo.pCurPresentation = pMultipart;
2216                 }
2217
2218                 /* first multipart */
2219                 if (pLastMultipart == NULL) {
2220                         pMsgBody->body.pMultipart = pMultipart;
2221                         pLastMultipart = pMultipart;
2222                         pPreMultipart = NULL;
2223                 } else {
2224                         pLastMultipart->pNext = pMultipart;
2225                         pLastMultipart = pMultipart;
2226                         pPreMultipart = pMultipart;
2227                 }
2228
2229                 pMsgType->contentSize += pMultipart->pBody->size;
2230
2231                 nEntries--;
2232
2233                 __MmsDebugPrintMulitpartEntry(pMultipart, index++);
2234
2235         }
2236
2237         pMsgBody->size = totalLength - pMsgBody->offset;
2238
2239 #ifdef  __SUPPORT_DRM__
2240         if (MmsDrm2GetConvertState() != MMS_DRM2_CONVERT_REQUIRED)
2241 #endif
2242                 __MsgConfirmPresentationPart(pMsgType, pMsgBody, &presentationInfo);
2243
2244         if (__MsgResolveNestedMultipart(pMsgType, pMsgBody) == false) {
2245                 MSG_DEBUG("MmsBinaryDecodeMultipart : MsgResolveNestedMultipart failed \n");
2246                 goto __CATCH;
2247         }
2248
2249 __RETURN:
2250         return true;
2251
2252 __CATCH:
2253         if (pMultipart) {
2254                 if (pMultipart->pBody) {
2255                         free(pMultipart->pBody);
2256                         pMultipart->pBody = NULL;
2257                 }
2258
2259                 free(pMultipart);
2260                 pMultipart = NULL;
2261         }
2262
2263         return false;
2264 }
2265
2266 static bool __MmsBinaryDecodeEachPart(FILE *pFile, char *szFilePath, MsgType *pMsgType, MsgBody *pMsgBody, int totalLength)
2267 {
2268         int     length = 0;
2269         bool bSuccess = false;
2270         UINT32 headerLength = 0;
2271         UINT32 bodyLength = 0;
2272         int offset = 0;
2273
2274         MSG_DEBUG("MmsBinaryDecodeEachPart: total length=%d\n", totalLength);
2275
2276         /* header length */
2277
2278         if (__MmsBinaryDecodeUintvar(pFile, &headerLength, totalLength) <= 0) {
2279                 MSG_DEBUG("MmsBinaryDecodeEachPart: Get header length fail \n");
2280                 goto __CATCH;
2281         }
2282
2283         offset = __MmsGetDecodeOffset();
2284         if (offset >= totalLength)
2285                 goto __RETURN;
2286
2287
2288         /* body length */
2289
2290         if (__MmsBinaryDecodeUintvar(pFile, &bodyLength, totalLength) <= 0) {
2291                 MSG_DEBUG("MmsBinaryDecodeEachPart: Get body length fail\n");
2292                 goto __CATCH;
2293         }
2294
2295
2296         offset = __MmsGetDecodeOffset();
2297         if (offset >= totalLength)
2298                 goto __RETURN;
2299
2300
2301         /* Content Type */
2302         if (szFilePath != NULL)
2303                 strncpy(pMsgType->szOrgFilePath, szFilePath, strlen(szFilePath));
2304
2305         pMsgType->offset = __MmsGetDecodeOffset();
2306         pMsgType->size = headerLength;
2307         pMsgType->contentSize = bodyLength;
2308
2309         if (pMsgType->offset > totalLength)
2310                 goto __RETURN;
2311
2312         length = __MmsBinaryDecodeContentType(pFile, pMsgType, totalLength);
2313         if (length <= 0) {
2314                 MSG_DEBUG("MmsBinaryDecodeEachPart: Decode contentType Fail \n");
2315                 goto __CATCH;
2316         }
2317
2318         offset = __MmsGetDecodeOffset();
2319         if (offset >= totalLength)
2320                 goto __RETURN;
2321
2322
2323         /* Part Header */
2324
2325         if (__MmsBinaryDecodePartHeader(pFile, pMsgType, headerLength - length, totalLength) == false) {
2326                 MSG_DEBUG("MmsBinaryDecodeEachPart: Decode contentHeader Fail \n");
2327                 goto __CATCH;
2328         }
2329
2330         offset = __MmsGetDecodeOffset();
2331         if (offset >= totalLength)
2332                 goto __RETURN;
2333
2334         /* Part Body */
2335
2336         if (szFilePath != NULL)
2337                 strncpy(pMsgBody->szOrgFilePath, szFilePath, strlen(szFilePath));
2338
2339         pMsgBody->offset = __MmsGetDecodeOffset();
2340         pMsgBody->size   = bodyLength;
2341
2342         if (pMsgBody->offset > totalLength)
2343                 goto __RETURN;
2344
2345         switch (pMsgType->type) {
2346         case MIME_APPLICATION_VND_WAP_MULTIPART_MIXED:
2347         case MIME_APPLICATION_VND_WAP_MULTIPART_RELATED:
2348         case MIME_APPLICATION_VND_WAP_MULTIPART_ASTERIC:
2349         case MIME_APPLICATION_VND_WAP_MULTIPART_ALTERNATIVE:
2350         case MIME_MULTIPART_REPORT:
2351         case MIME_MULTIPART_MIXED:
2352         case MIME_MULTIPART_RELATED:
2353         case MIME_MULTIPART_ALTERNATIVE:
2354
2355                 MSG_DEBUG("MmsBinaryDecodeEachPart: Decode multipart\n");
2356
2357                 if (__MmsBinaryDecodeMultipart(pFile, szFilePath, pMsgType, pMsgBody, totalLength) == false) {
2358                         MSG_DEBUG("MmsBinaryDecodeEachPart: MmsBinaryDecodeMultipart is fail.\n");
2359                         goto __CATCH;
2360                 }
2361
2362                 offset = __MmsGetDecodeOffset();
2363                 if (offset >= totalLength)
2364                         goto __RETURN;
2365
2366                 break;
2367
2368
2369 #ifdef __SUPPORT_DRM__
2370
2371         case MIME_APPLICATION_VND_OMA_DRM_MESSAGE: /* Contains forwardLock OR combined-delivery media part */
2372                 MSG_DEBUG("MmsBinaryDecodeEachPart: MIME_APPLICATION_VND_OMA_DRM_MESSAGE Part \n");
2373
2374                 if (MmsDrm2GetConvertState() != MMS_DRM2_CONVERT_NOT_FIXED && MmsDrm2GetConvertState() != MMS_DRM2_CONVERT_REQUIRED) {
2375
2376                         if (__MmsBinaryDecodeDRMContent(pFile, szFilePath, pMsgType, pMsgBody, bodyLength, totalLength) == false)
2377                                 goto __CATCH;
2378                 } else {
2379                         MmsDrm2SetConvertState(MMS_DRM2_CONVERT_REQUIRED);
2380
2381                         bSuccess = __MmsBinaryDecodePartBody(pFile, bodyLength, totalLength);
2382                         if (bSuccess == false) {
2383                                 MSG_DEBUG("MmsBinaryDecodeEachPart: Decode contentBody Fail \n");
2384                                 goto __CATCH;
2385                         }
2386                 }
2387                 offset = __MmsGetDecodeOffset();
2388                 if (offset >= totalLength)
2389                         goto __RETURN;
2390
2391                 break;
2392
2393         case MIME_APPLICATION_VND_OMA_DRM_CONTENT: /* Contains seperate-delivery media part (DCF) */
2394
2395                 MSG_DEBUG("MmsBinaryDecodeEachPart: MIME_APPLICATION_VND_OMA_DRM_CONTENT Part \n");
2396
2397                 if (__MmsBinaryDecodeDRMContent(pFile, szFilePath, pMsgType, pMsgBody, bodyLength, totalLength) == false)
2398                         goto __CATCH;
2399
2400                 offset = __MmsGetDecodeOffset();
2401                 if (offset >= totalLength)
2402                         goto __RETURN;
2403
2404                 break;
2405 #endif
2406
2407         default:
2408                 MSG_DEBUG("MmsBinaryDecodeEachPart: Other normal Part \n");
2409
2410                 bSuccess = __MmsBinaryDecodePartBody(pFile, bodyLength, totalLength);
2411                 if (bSuccess == false) {
2412                         MSG_DEBUG("MmsBinaryDecodeEachPart: Decode contentBody Fail \n");
2413                         goto __CATCH;
2414                 }
2415
2416                 offset = __MmsGetDecodeOffset();
2417                 if (offset >= totalLength)
2418                         goto __RETURN;
2419
2420                 break;
2421         }
2422
2423         return true;
2424
2425 __RETURN:
2426
2427         return true;
2428
2429 __CATCH:
2430
2431         return false;
2432 }
2433
2434 #ifdef __SUPPORT_DRM__
2435 static bool __MmsBinaryDecodeDRMContent(FILE *pFile, char *szFilePath, MsgType *pMsgType, MsgBody *pMsgBody, unsigned int bodyLength, int totalLength)
2436 {
2437         int offset = 0;
2438         char szTempFilePath[MSG_FILEPATH_LEN_MAX] = MSG_DATA_PATH"drm.dcf";
2439         char *pRawData = NULL;
2440         bool isFileCreated = false;
2441
2442         MSG_DEBUG("bodyLength: %d\n", bodyLength);
2443
2444         offset = __MmsGetDecodeOffset();
2445
2446         if (offset >= totalLength)
2447                 goto __RETURN;
2448
2449         if (szFilePath != NULL)
2450                 strncpy(pMsgBody->szOrgFilePath, szFilePath, strlen(szFilePath));
2451         if (szFilePath != NULL)
2452                 strncpy(pMsgType->szOrgFilePath, szFilePath, strlen(szFilePath));
2453
2454         pRawData = (char *)malloc(bodyLength);
2455         if (pRawData == NULL) {
2456                 MSG_DEBUG("pRawData alloc FAIL \n");
2457                 goto __CATCH;
2458         }
2459
2460         if (MsgFseek(pFile, offset, SEEK_SET) < 0) {
2461                 MSG_DEBUG("MsgFseek() returns -1 \n");
2462                 goto __CATCH;
2463         }
2464         if (MsgReadFile(pRawData, sizeof(char), bodyLength, pFile) != (size_t)bodyLength) {
2465                 MSG_DEBUG("FmReadFile() returns false \n");
2466                 goto __CATCH;
2467         }
2468         if (MsgOpenCreateAndOverwriteFile(szTempFilePath, pRawData, bodyLength) == false) {
2469                 MSG_DEBUG("MsgOpenCreateAndOverwriteFile() returns false \n");
2470                 goto __CATCH;
2471         }
2472
2473         isFileCreated = true;
2474         MSG_DEBUG("MmsDrm2GetConvertState() [%d]", MmsDrm2GetConvertState());
2475
2476         if (pMsgType->type == MIME_APPLICATION_VND_OMA_DRM_MESSAGE && (MmsDrm2GetConvertState() != MMS_DRM2_CONVERT_FINISH)) {
2477                 MmsDrm2SetConvertState(MMS_DRM2_CONVERT_REQUIRED);
2478         } else {
2479                 if (MsgDRM2GetDRMInfo(szTempFilePath, pMsgType) == false) {
2480                         MSG_DEBUG("MsgDRM2GetDRMInfo() returns false \n");
2481                         goto __CATCH;
2482                 }
2483         }
2484
2485         if(remove(szTempFilePath) != 0)
2486                 MSG_DEBUG("remove fail");
2487         isFileCreated = false;
2488
2489         if (__MmsBinaryDecodeMovePointer(pFile, offset + bodyLength, totalLength) == false)
2490                 goto __CATCH;
2491
2492 __RETURN:
2493
2494         if (pRawData) {
2495                 free(pRawData);
2496                 pRawData = NULL;
2497         }
2498
2499         return true;
2500
2501 __CATCH:
2502         if (isFileCreated)
2503                 if(remove(szTempFilePath) != 0)
2504                         MSG_DEBUG("remove fail");
2505
2506         if (pRawData) {
2507                 free(pRawData);
2508                 pRawData = NULL;
2509         }
2510
2511         return false;
2512 }
2513
2514 static int __MmsDrm2BinaryEncodeUintvarLen(UINT32 integer)
2515 {
2516         UINT32 length   = 0;
2517
2518         /* Find encoded unitvar length */
2519         if (integer  <= MMS_UINTVAR_LENGTH_1) {
2520                 length = 1;
2521         } else {
2522                 if (integer <= MMS_UINTVAR_LENGTH_2) {
2523                         length = 2;
2524                 } else {
2525                         if (integer <= MMS_UINTVAR_LENGTH_3) {
2526                                 length = 3;
2527                         } else {
2528                                 length = 4;
2529                         }
2530                 }
2531         }
2532
2533         return length;
2534 }
2535
2536 static bool __MmsDrm2BinaryEncodeUintvar(UINT32 integer, int length, char *pszOutput)
2537 {
2538         const char ZERO = 0x00;
2539         int i = 2;
2540         char szReverse[MSG_STDSTR_LONG] = {0, };
2541
2542         union {
2543                 UINT32 integer;
2544                 char bytes[4];
2545         } source;
2546         source.integer = integer;
2547         memset(szReverse, 0, MSG_STDSTR_LONG);
2548
2549         /* Seperate integer to 4 1 byte integer */
2550         szReverse[3] = source.bytes[3] & 0x0f;
2551         szReverse[0] = source.bytes[0];
2552         szReverse[0] = szReverse[0] & 0x7f;
2553
2554         while (length >= i) {// initially, i = 2
2555                 /* Move integer bit to proper position */
2556                 source.integer = source.integer << 1;
2557                 source.integer = source.integer >> 8;
2558                 source.bytes[3] = ZERO;
2559
2560                 /* Retrive 1 encode uintvar */
2561                 szReverse[i-1] = source.bytes[0];
2562                 szReverse[i-1] = szReverse[i-1] | 0x80;
2563                 i++;
2564         }
2565
2566         for (i=0; i < length; i++)
2567                 pszOutput[i] = szReverse[length - i - 1];
2568
2569         return true;
2570 }
2571
2572 static int __MmsDrm2GetEntriesValueLength(FILE *pFile, int orgOffset)
2573 {
2574         char szEntries[5] = {0, };
2575         UINT8 oneByte   = 0;
2576         int j = 0;                      //j is the length of nEntries value
2577
2578         if (MsgReadFile(szEntries, sizeof(char), 4, pFile) != (size_t)4) {
2579                 MSG_DEBUG("__MmsDrm2GetEntriesValueLength: FmReadFile() returns false \n");
2580                 return false;
2581         }
2582
2583         while (true) {
2584                 oneByte = szEntries[j++];
2585
2586                 if (oneByte <= 0x7f)
2587                         break;
2588         }
2589
2590         //move file pointer to point nEntries
2591         if (MsgFseek(pFile, orgOffset, SEEK_SET) < 0) {
2592                 MSG_DEBUG("__MmsDrm2GetEntriesValueLength: fail to seek file pointer\n");
2593                 return false;
2594         }
2595
2596         return j;
2597 }
2598
2599 static bool __MmsDrm2WriteDataToConvertedFile(FILE *pSrcFile, FILE *pDestinationFile, char *pszMmsLoadTempBuf, int length, int bufLen)
2600 {
2601         int loadLen = 0, totalLoadLen = 0, nRead = 0;
2602
2603         for (int i=0; i<(length/bufLen)+1; i++) {
2604                 loadLen = (length-totalLoadLen < bufLen) ? length-totalLoadLen : bufLen;
2605
2606                 memset(pszMmsLoadTempBuf, 0, MMS_DRM2_CONVERT_BUFFER_MAX + 1);
2607
2608                 if (MsgReadFile(pszMmsLoadTempBuf, sizeof(char), loadLen, pSrcFile) != (size_t)loadLen) {
2609                         MSG_DEBUG("__MmsDrm2WriteDataToConvertedFile: FmReadFile() returns false \n");
2610                         return false;
2611                 }
2612
2613                 if (MsgWriteFile(pszMmsLoadTempBuf, sizeof(char), loadLen, pDestinationFile) != (size_t)loadLen) {
2614                         MSG_DEBUG("__MmsDrm2WriteDataToConvertedFile: File Writing is failed.\n");
2615                         return false;
2616                 }
2617
2618                 totalLoadLen += nRead;
2619         }
2620
2621         return true;
2622 }
2623
2624 /*************************************************************************
2625  * description : make new message file converting CD & FL part of original message file to SD type
2626  * argument : void
2627  * return value
2628     - bool :  result of converting
2629 **************************************************************************/
2630 bool MmsDrm2ConvertMsgBody(char *szOriginFilePath)
2631 {
2632         FILE *pFile = NULL;
2633         FILE *hConvertedFile = NULL;
2634         FILE *hTempFile = NULL;
2635         FILE *hFile = NULL;
2636         MsgMultipart *pMultipart = NULL;
2637         char szTempFilePath[MSG_FILEPATH_LEN_MAX] = MSG_DATA_PATH"Drm_Convert";
2638         char szTempFile[MSG_FILEPATH_LEN_MAX] = MSG_DATA_PATH"temp.dm";
2639         char *pszMmsLoadTempBuf = NULL;
2640         char *pszOrgData = NULL;
2641         int length = 0;
2642         int bufLen = MMS_DRM2_CONVERT_BUFFER_MAX;
2643         int curOffset = 0;
2644
2645         MSG_DEBUG("start convert~~~~~~\n");
2646
2647         pFile = MsgOpenFile(szOriginFilePath, "rb");
2648         if (pFile == NULL) {
2649                 MSG_DEBUG("Open decode temporary file fail\n");
2650                 goto __CATCH;
2651         }
2652
2653         hConvertedFile = MsgOpenFile(MMS_DECODE_DRM_CONVERTED_TEMP_FILE, "wb+");
2654         if (hConvertedFile == NULL) {
2655                 MSG_DEBUG("Open decode temporary file fail\n");
2656                 goto __CATCH;
2657         }
2658
2659         pszMmsLoadTempBuf = (char*)malloc(MMS_DRM2_CONVERT_BUFFER_MAX + 1);
2660         if (pszMmsLoadTempBuf == NULL) {
2661                 MSG_DEBUG("malloc for pszMmsLoadTempBuf failed\n");
2662                 goto __CATCH;
2663         }
2664         memset(pszMmsLoadTempBuf, 0, MMS_DRM2_CONVERT_BUFFER_MAX + 1);
2665
2666         // MMS Header  copy
2667         length = mmsHeader.msgBody.offset;
2668         if (__MmsDrm2WriteDataToConvertedFile(pFile, hConvertedFile, pszMmsLoadTempBuf, length, bufLen) == false) {
2669                 MSG_DEBUG("Write header data fail\n");
2670                 goto __CATCH;
2671         }
2672
2673         curOffset += length;    //change offset
2674
2675         // MMS Body copy
2676         if (MsgIsMultipart(mmsHeader.msgType.type) == true)
2677         {
2678                 // nEntries copy
2679                 length = __MmsDrm2GetEntriesValueLength(pFile, curOffset);      // getting nEntries value's length
2680
2681                 if (__MmsDrm2WriteDataToConvertedFile(pFile, hConvertedFile, pszMmsLoadTempBuf, length, bufLen) == false) {
2682                         MSG_DEBUG("Write nEntries fail\n");
2683                         goto __CATCH;
2684                 }
2685
2686                 curOffset += length;    //change offset
2687
2688                 // each Multipart entry copy
2689                 pMultipart = mmsHeader.msgBody.body.pMultipart;
2690
2691                 while (pMultipart) {
2692                         if (pMultipart->type.type == MIME_APPLICATION_VND_OMA_DRM_MESSAGE) {
2693                                 int orgDataLen = pMultipart->pBody->size;
2694                                 int nSize = 0;
2695
2696                                 MSG_DEBUG("Write MIME_APPLICATION_VND_OMA_DRM_MESSAGE multipart data(orgDataLen = %d).\n", orgDataLen);
2697
2698                                 pszOrgData = (char *)malloc(orgDataLen + 1);
2699                                 if (pszOrgData == NULL) {
2700                                         MSG_DEBUG("pszOrgData is NULL \n");
2701                                         goto __CATCH;
2702                                 }
2703                                 memset(pszOrgData, 0, orgDataLen + 1);
2704
2705                                 // move file pointer to data
2706                                 if (MsgFseek(pFile, pMultipart->pBody->offset, SEEK_SET) < 0) {
2707                                         MSG_DEBUG("fail to seek file pointer 1\n");
2708                                         goto __CATCH;
2709                                 }
2710
2711                                 if (MsgReadFile(pszOrgData, sizeof(char), orgDataLen, pFile) != (size_t)orgDataLen) {
2712                                         MSG_DEBUG("FmReadFile() returns false for orgData\n");
2713                                         goto __CATCH;
2714                                 }
2715
2716                                 if((hFile = MsgOpenFile(szTempFile, "wb+")) == NULL) {
2717                                         MSG_DEBUG("file open failed [%s]", szTempFile);
2718                                         goto __CATCH;
2719                                 }
2720
2721                                 if (MsgWriteFile(pszOrgData, sizeof(char), orgDataLen, hFile) != (size_t)orgDataLen) {
2722                                         MSG_DEBUG("File write error");
2723                                         goto __CATCH;
2724                                 }
2725
2726                                 if (pszOrgData) {
2727                                         free(pszOrgData);
2728                                         pszOrgData = NULL;
2729                                 }
2730
2731                                 MsgFflush(hFile);
2732                                 MsgCloseFile(hFile);
2733
2734                                 hFile = NULL;
2735
2736                                 // --> invoking drm agent api, converting data part start
2737                                 MSG_DEBUG("start data part convert by callling drm agent api\n");
2738
2739                                 int ret = 0;
2740                                 ret = MsgDrmConvertDmtoDcfType(szTempFile, szTempFilePath);
2741                                 MSG_DEBUG("MsgDrmConvertDmtoDcfType returned %s", ret ? "true": "false");
2742
2743                                 if (MsgGetFileSize(szTempFilePath, &nSize) == false) {
2744                                         MSG_DEBUG("MsgGetFileSize error");
2745                                         goto __CATCH;
2746                                 }
2747                                 MSG_DEBUG("end data part convert(converted data len = %d)\n", nSize);
2748
2749                                 // move file pointer to the head of multipart
2750                                 if (MsgFseek(pFile, curOffset, SEEK_SET) < 0) {
2751                                         MSG_DEBUG("fail to seek file pointer 2\n");
2752                                         goto __CATCH;
2753                                 }
2754
2755                                 // read headerLen, dataLen
2756                                 length = pMultipart->type.offset - curOffset;
2757                                 memset(pszMmsLoadTempBuf, 0, MMS_DRM2_CONVERT_BUFFER_MAX + 1);
2758                                 if (MsgReadFile(pszMmsLoadTempBuf, sizeof(char), length, pFile) != (size_t)length) {
2759                                         MSG_DEBUG("FmReadFile() returns false for headerLen, dataLen\n");
2760                                         goto __CATCH;
2761                                 }
2762
2763                                 curOffset += length;
2764
2765                                 // change dataLen based on converted data
2766                                 {
2767                                         UINT8   oneByte = 0;
2768                                         int             j = 0;
2769                                         int             encodeLen = 0;
2770                                         char    szOutput[MSG_STDSTR_LONG] = {0, };
2771
2772                                         while (true) {
2773                                                 oneByte = pszMmsLoadTempBuf[j++];
2774
2775                                                 if (oneByte <= 0x7f)
2776                                                         break;
2777                                         }
2778
2779                                         encodeLen = __MmsDrm2BinaryEncodeUintvarLen((UINT32)nSize);
2780                                         __MmsDrm2BinaryEncodeUintvar((UINT32)nSize, encodeLen, szOutput);
2781
2782                                         strncpy(&(pszMmsLoadTempBuf[j]), szOutput, encodeLen);
2783                                         pszMmsLoadTempBuf[j+encodeLen] = '\0';
2784
2785                                         if (MsgWriteFile(pszMmsLoadTempBuf, sizeof(char), length, hConvertedFile) != (size_t)length) {
2786                                                 MSG_DEBUG("Drm2WriteConvertData: FmWriteFile() returns false for dateLen\n");
2787                                                 goto __CATCH;
2788                                         }
2789                                 }
2790
2791
2792                                 length = pMultipart->pBody->offset - pMultipart->type.offset;
2793
2794                                 if (__MmsDrm2WriteDataToConvertedFile(pFile, hConvertedFile, pszMmsLoadTempBuf, length, bufLen) == false) {
2795                                         MSG_DEBUG("Drm2WriteConvertData: Write content type, headers fail\n");
2796                                         goto __CATCH;
2797                                 }
2798
2799                                 curOffset += length;
2800
2801                                 // write converted data
2802                                 hTempFile = MsgOpenFile(szTempFilePath, "rb");
2803                                 if (hTempFile == NULL) {
2804                                         MSG_DEBUG("Open decode temporary file fail\n");
2805                                         goto __CATCH;
2806                                 }
2807
2808                                 length = nSize;
2809
2810                                 if (__MmsDrm2WriteDataToConvertedFile(hTempFile, hConvertedFile, pszMmsLoadTempBuf, length, bufLen) == false) {
2811                                         MSG_DEBUG("Write converted data fail\n");
2812                                         goto __CATCH;
2813                                 }
2814
2815                                 if (hTempFile != NULL) {
2816                                         MsgCloseFile(hTempFile);
2817                                         hTempFile = NULL;
2818                                 }
2819
2820                                 curOffset += pMultipart->pBody->size;
2821
2822                                 // move file pointer to the head of multipart
2823                                 if (MsgFseek(pFile, curOffset, SEEK_SET) < 0) {
2824                                         MSG_DEBUG("fail to seek file pointer \n");
2825                                         goto __CATCH;
2826                                 }
2827                         } else {        // it doesn't need to convert if it is not CD or FL
2828                                 MSG_DEBUG("Write normal multipart data\n");
2829
2830                                 length = pMultipart->pBody->offset + pMultipart->pBody->size - curOffset;
2831
2832                                 if (__MmsDrm2WriteDataToConvertedFile(pFile, hConvertedFile, pszMmsLoadTempBuf, length, bufLen) == false) {
2833                                         MSG_DEBUG("Write multipart data fail \n");
2834                                         goto __CATCH;
2835                                 }
2836
2837                                 curOffset += length;
2838                         }
2839
2840                         pMultipart = pMultipart->pNext;
2841                 }
2842         }
2843
2844         MSG_DEBUG("end convert~~~~~~\n");
2845
2846         if (pFile != NULL) {
2847                 MsgCloseFile(pFile);
2848                 pFile = NULL;
2849         }
2850
2851         if (hConvertedFile != NULL) {
2852                 MsgCloseFile(hConvertedFile);
2853                 hConvertedFile = NULL;
2854         }
2855
2856         if (pszMmsLoadTempBuf) {
2857                 free(pszMmsLoadTempBuf);
2858                 pszMmsLoadTempBuf = NULL;
2859         }
2860
2861         if(remove(szTempFile) != 0)
2862                 MSG_DEBUG("remove fail");
2863         if(remove(szTempFilePath) != 0)
2864                 MSG_DEBUG("remove fail");
2865
2866         return true;
2867
2868 __CATCH:
2869
2870         if (pFile != NULL) {
2871                 MsgCloseFile(pFile);
2872                 pFile = NULL;
2873         }
2874
2875         if (hConvertedFile != NULL) {
2876                 MsgCloseFile(hConvertedFile);
2877                 hConvertedFile = NULL;
2878         }
2879
2880         if (hTempFile != NULL) {
2881                 MsgCloseFile(hTempFile);
2882                 hTempFile = NULL;
2883         }
2884
2885         if (pszMmsLoadTempBuf) {
2886                 free(pszMmsLoadTempBuf);
2887                 pszMmsLoadTempBuf = NULL;
2888         }
2889
2890         if (pszOrgData) {
2891                 free(pszOrgData);
2892                 pszOrgData = NULL;
2893         }
2894
2895         if (hFile != NULL)
2896         {
2897                 MsgCloseFile(hFile);
2898                 hFile = NULL;
2899         }
2900
2901         if (remove(szTempFile) != 0)
2902                 MSG_DEBUG("remove fail");
2903
2904         if (remove(szTempFilePath) != 0)
2905                 MSG_DEBUG("remove fail");
2906
2907         if (remove(MMS_DECODE_DRM_CONVERTED_TEMP_FILE) != 0)
2908                 MSG_DEBUG("remove fail");       //remove convertin result if it goes to __CATCH
2909
2910         return false;
2911 }
2912
2913 /*************************************************************************
2914  * description : Function for decoding a converted file
2915  * argument : void
2916  * return value
2917     - bool :  result of converting
2918 **************************************************************************/
2919
2920 bool MmsDrm2ReadMsgConvertedBody(MSG_MESSAGE_INFO_S *pMsg, bool bSavePartsAsTempFiles, bool bRetrieved, char *retrievedPath)
2921 {
2922         MmsMsg *pMmsMsg;
2923         MmsPluginStorage::instance()->getMmsMessage(&pMmsMsg);
2924         MmsUnregisterDecodeBuffer();
2925 #ifdef __SUPPORT_DRM__
2926         MmsReleaseMsgDRMInfo(&pMmsMsg->msgType.drmInfo);
2927 #endif
2928         MmsReleaseMsgBody(&pMmsMsg->msgBody, pMmsMsg->msgType.type);
2929
2930         if (MmsReadMsgBody(pMsg->msgId, bSavePartsAsTempFiles, bRetrieved, retrievedPath) == false) {
2931                 MSG_DEBUG("MmsDrm2ReadMsgConvertedBody: _MmsReadMsgBody with converted file is failed\n");
2932                 return false;
2933         }
2934
2935         return true;
2936 }
2937
2938 #endif
2939
2940 /* --------------------------------------------------------------------
2941  *
2942  *     B  I  N  A  R  Y       D  E  C  D  E      U  T  I  L  I  T  Y
2943  *
2944  * --------------------------------------------------------------------*/
2945
2946 bool __MmsBinaryDecodeGetOneByte(FILE *pFile, UINT8 *pOneByte, int totalLength)
2947 {
2948         int length = gMmsDecodeMaxLen - gCurMmsDecodeBuffPos;
2949
2950         if (pFile == NULL || pOneByte == NULL)
2951         {
2952                 MSG_DEBUG("_MmsBinaryDecodeGetOneByte: invalid file or buffer\n");
2953                 goto __CATCH;
2954         }
2955
2956         if (length < 1) {
2957                 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
2958                                                                            gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
2959                         MSG_DEBUG("_MmsBinaryDecodeGetOneByte: fail to load to buffer \n");
2960                         goto __CATCH;
2961                 }
2962         }
2963
2964         *pOneByte = gpCurMmsDecodeBuff[gCurMmsDecodeBuffPos++];
2965
2966         return true;
2967
2968 __CATCH:
2969         return false;
2970 }
2971
2972 /*
2973  * @remark: bufLen < gMmsDecodeMaxLen
2974  */
2975 bool __MmsBinaryDecodeGetBytes(FILE *pFile, char *szBuff, int bufLen, int totalLength)
2976 {
2977         int length = gMmsDecodeMaxLen - gCurMmsDecodeBuffPos;
2978         int i = 0;
2979
2980
2981         if (pFile == NULL || szBuff == NULL || bufLen == 0 || bufLen > gMmsDecodeMaxLen)
2982                 goto __CATCH;
2983
2984         memset(szBuff, 0, bufLen);
2985
2986         if (length < bufLen) {
2987                 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
2988                                                                            gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
2989                         MSG_DEBUG("_MmsBinaryDecodeGetBytes: fail to load to buffer \n");
2990                         goto __CATCH;
2991                 }
2992         }
2993
2994         for (i = 0; i < bufLen - 1; i++)
2995                 szBuff[i] = gpCurMmsDecodeBuff[gCurMmsDecodeBuffPos++];
2996
2997
2998         gCurMmsDecodeBuffPos++; //NULL
2999
3000         return true;
3001
3002 __CATCH:
3003         return false;
3004 }
3005
3006 bool __MmsBinaryDecodeGetLongBytes(FILE *pFile, char *szBuff, int bufLen, int totalLength)
3007 {
3008         int iPos = 0;
3009
3010         if (pFile == NULL || szBuff == NULL || bufLen == 0)
3011                 goto __CATCH;
3012
3013         memset(szBuff, 0, bufLen);
3014
3015         if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
3016                                                                    gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
3017                 MSG_DEBUG("_MmsBinaryDecodeGetLongBytes: fail to load to buffer \n");
3018                 goto __CATCH;
3019         }
3020
3021         while ((bufLen - iPos) >= gMmsDecodeMaxLen) {
3022                 if (__MmsBinaryDecodeGetBytes(pFile, szBuff + iPos, gMmsDecodeMaxLen, totalLength) == false) {
3023                         MSG_DEBUG("_MmsBinaryDecodeGetLongBytes: 1. _MmsBinaryDecodeGetBytes fail \n");
3024                         goto __CATCH;
3025                 }
3026
3027                 iPos += gMmsDecodeMaxLen;
3028         }
3029
3030         if ((bufLen - iPos) > 0) {
3031                 if (__MmsBinaryDecodeGetBytes(pFile, szBuff + iPos, (bufLen - iPos), totalLength) == false) {
3032                         MSG_DEBUG("_MmsBinaryDecodeGetLongBytes: 2. _MmsBinaryDecodeGetBytes fail \n");
3033                         goto __CATCH;
3034                 }
3035
3036                 iPos += (bufLen - iPos);
3037         }
3038
3039         return true;
3040
3041 __CATCH:
3042         return false;
3043 }
3044
3045 /**
3046  * Decode uintvar to 32bit unsigned integer
3047  *
3048  * @param       pEncodedData    [in] encoded data
3049  * @param       pUintVar                [out] Decode uintvar (32bit unsigned integer)
3050  * @return      The length of uintvar (-1, if cannot be converted to a uintvar)
3051  *
3052  * 0 XXXXXXX -> 0-bit: continue bit & 1~7bit: integer value
3053  * - -------
3054  */
3055 static const UINT32 uintvarDecodeTable[] = { 0x00000001, 0x00000080, 0x00004000, 0x00100000, 0x08000000 };
3056
3057 static int __MmsBinaryDecodeUintvar(FILE *pFile, UINT32 *pUintVar, int totalLength)
3058 {
3059         UINT8 count = 0;
3060         UINT8 oneByte = 0;
3061         UINT32 decodedUintvar = 0;
3062         UINT8 iBuff[5] = {0};
3063         int length = MSG_MMS_DECODE_BUFFER_MAX - gCurMmsDecodeBuffPos;
3064
3065
3066         if (pFile == NULL || pUintVar == NULL)
3067                 return -1;
3068
3069         if (length < 5) {
3070                 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
3071                                                                            gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
3072                         MSG_DEBUG("__MmsBinaryDecodeUintvar: fail to load to buffer \n");
3073                         goto __CATCH;
3074                 }
3075         }
3076
3077         while (true) {
3078                 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false)
3079                         goto __CATCH;
3080
3081                 if (oneByte > 0x7f)     {
3082                         iBuff[count++] = oneByte;
3083                 } else {
3084                         iBuff[count++] = oneByte;
3085                         break;
3086                 }
3087
3088                 if (count > 4) {
3089                         MSG_DEBUG("__MmsBinaryDecodeUintvar : legnth is too long\n");
3090                         goto __CATCH;
3091                 }
3092         }
3093
3094         for (int i = 0; i < count; i++)
3095                 decodedUintvar += (uintvarDecodeTable[i] * (iBuff[count-(i+1)]&0x7f));
3096
3097         *pUintVar = decodedUintvar;
3098
3099         return count;
3100
3101 __CATCH:
3102         gCurMmsDecodeBuffPos -= count;
3103         return -1;
3104 }
3105
3106 /**
3107  * Decode uintvar to 32bit unsigned integer by uintvar length
3108  *
3109  * @param       pEncodedData [in] uintvar encoded data
3110  * @param       length           [in] length of integer value
3111  * @return      unsigned integer value
3112  */
3113 static UINT32 __MmsHeaderDecodeIntegerByLength(FILE *pFile, UINT32 length, int totalLength)
3114 {
3115         UINT32 i = 0;
3116         UINT8 oneByte = 0;
3117         char *pData = NULL;
3118         union {
3119                 UINT32  integer;
3120                 UINT8   seg[4];
3121         } returner;
3122
3123         returner.integer = 0;
3124
3125         if (length > 4)
3126                 length = 4;
3127
3128         if (length == 1)
3129         {
3130                 if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
3131                         MSG_DEBUG("__MmsHeaderDecodeIntegerByLength: _MmsBinaryDecodeGetOneByte fail\n");
3132                         return oneByte;
3133                 }
3134
3135                 if (oneByte > 0x7f) {
3136                         return (oneByte & 0x7f);
3137                 } else {
3138                         return oneByte;
3139                 }
3140         }
3141
3142         if (length == 0)
3143                 return 0;
3144
3145         pData = (char *)malloc(length + 1);
3146         if (pData == NULL) {
3147                 MSG_DEBUG("__MmsHeaderDecodeIntegerByLength: pData alloc fail\n");
3148                 goto __CATCH;
3149         }
3150         memset(pData, 0, length + 1);
3151
3152         if (__MmsBinaryDecodeGetBytes(pFile, pData, length + 1, totalLength) == false) {
3153                 MSG_DEBUG("__MmsHeaderDecodeIntegerByLength: _MmsBinaryDecodeGetOneByte fail\n");
3154                 goto __CATCH;
3155         }
3156
3157         gCurMmsDecodeBuffPos--; // - NULL
3158
3159         for (i= 0; i < length; i++)
3160                 returner.seg[length - (i+1)] = pData[i];
3161
3162         if (pData) {
3163                 free(pData);
3164                 pData = NULL;
3165         }
3166
3167         return returner.integer;
3168
3169 __CATCH:
3170
3171         if (pData) {
3172                 free(pData);
3173                 pData = NULL;
3174         }
3175
3176         return returner.integer;
3177 }
3178
3179 /**
3180  * Decode uintvar to 32bit unsigned integer by uintvar length
3181  *
3182  * @param       pEncodedData    [in]  uintvar encoded data
3183  * @param       pInteger                [out] Decode integer value (long/short)
3184  * @return      unsigned integer value (-1, if cannot be converted to unsigned integer value)
3185  */
3186 static bool __MmsBinaryDecodeInteger(FILE *pFile, UINT32 *pInteger, int *pIntLen, int totalLength)
3187 {
3188         UINT8 oneByte   = 0;
3189         char *pData     = NULL;
3190         union {
3191                 UINT32  integer;
3192                 UINT8   seg[4];
3193         } returner;
3194
3195
3196         if (pInteger == NULL)
3197                 return false;
3198
3199         returner.integer = 0;
3200         *pIntLen                 = 0;
3201
3202         if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
3203                 MSG_DEBUG("__MmsBinaryDecodeInteger: GetOneByte fail\n");
3204                 return false;
3205         }
3206
3207         if (oneByte < 0x1F)                             /* long integer : WAP-230-WSP-20010118-p, Proposed Version 18 January 2001 (pp.86) */
3208         {
3209                 pData = (char *)malloc(oneByte + 1);
3210                 if (pData == NULL) {
3211                         MSG_DEBUG("__MmsBinaryDecodeInteger: pData memalloc fail\n");
3212                         goto __CATCH;
3213                 }
3214                 memset(pData, 0, oneByte + 1);
3215
3216                 // Even NULL is copied in the _MmsBinaryDecodeGetBytes
3217                 if (__MmsBinaryDecodeGetBytes(pFile, pData, oneByte + 1, totalLength) == false) {
3218                         MSG_DEBUG("__MmsBinaryDecodeInteger: GetBytes fail\n");
3219                         goto __CATCH;
3220                 }
3221
3222                 gCurMmsDecodeBuffPos--; // - NULL
3223
3224                 int             length  = 0;
3225                 if (oneByte > 4) {
3226                         length = 4;
3227                 } else {
3228                         length = oneByte;
3229                 }
3230
3231                 int             i = 0;
3232                 for (i = 0; i < length; i++)
3233                         returner.seg[length - (i+1)] = pData[i];
3234
3235                 *pInteger = returner.integer;
3236                 *pIntLen  = oneByte + 1;
3237         } else if (oneByte >= 0x80)     {
3238                 /* short integer : WAP-230-WSP-20010118-p, Proposed Version 18 January 2001 (pp.86) */
3239                 *pInteger = oneByte & 0x7f;
3240                 *pIntLen  = 1;
3241         } else {
3242                 goto __CATCH;
3243         }
3244
3245         if (pData) {
3246                 free(pData);
3247                 pData = NULL;
3248         }
3249
3250         return true;
3251
3252 __CATCH:
3253
3254         gCurMmsDecodeBuffPos--;
3255
3256         if (pData) {
3257                 free(pData);
3258                 pData = NULL;
3259         }
3260
3261         return false;
3262 }
3263
3264 /**
3265  * Decode uintvar to 32bit unsigned integer by uintvar length
3266  *
3267  * @return      1  : Success
3268  *                      0  : This is not Value Length type data
3269  *                      -1 : Requires System error report
3270  */
3271 static int __MmsDecodeValueLength(FILE *pFile, UINT32 *pValueLength, int totalLength)
3272 {
3273         int length = 0;
3274         UINT32 uintvar = 0;
3275         UINT8 oneByte = 0;
3276
3277
3278         /*
3279          * value-length = short-length | (Length-quote Length)
3280          *                              = 0~30             | 31 + Uintvar-length
3281          */
3282
3283         if (pFile == NULL || pValueLength == NULL)
3284                 goto __CATCH;
3285
3286         *pValueLength = 0;
3287
3288         if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
3289                 gCurMmsDecodeBuffPos--;
3290                 goto __CATCH;
3291         }
3292
3293         if (0x00 < oneByte && oneByte < 0x1F) {
3294                 /* short-length */
3295
3296                 *pValueLength = oneByte;
3297                 length = 1;
3298         } else if (oneByte == 0x1F) {
3299                 /* Length-quote = 0x1F */
3300
3301                 length = __MmsBinaryDecodeUintvar(pFile, &uintvar, totalLength);
3302                 if (length == -1) {
3303                         MSG_DEBUG("__MmsDecodeValueLength: __MmsBinaryDecodeUintvar fail..\n");
3304                         goto __CATCH;
3305                 }
3306                 length ++;                                      // + length-quote
3307                 *pValueLength = uintvar;
3308         } else {
3309                 MSG_DEBUG("__MmsDecodeValueLength: not a value length type data\n");
3310                 gCurMmsDecodeBuffPos--;
3311                 return 0;
3312         }
3313
3314         return length;
3315
3316 __CATCH:
3317         MSG_DEBUG("__MmsDecodeValueLength: getting data fail\n");
3318         return -1;
3319 }
3320
3321 /**
3322  * Decode uintvar to 32bit unsigned integer by uintvar length
3323  *
3324  * @return      1  : Success
3325  *                      0  : This is not Value Length type data
3326  *                      -1 : Requires System error report
3327  * @ defference : if there is not length-quote, consider it as short length.
3328  */
3329 static int __MmsDecodeValueLength2(FILE *pFile, UINT32 *pValueLength, int totalLength)
3330 {
3331         int length      = 0;
3332         UINT32 uintvar = 0;
3333         UINT8 oneByte = 0;
3334
3335
3336         /*
3337          * value-length = short-length | (Length-quote Length)
3338          *                              = 0~30             | 31 + Uintvar-length
3339          */
3340
3341         if (pFile == NULL || pValueLength == NULL)
3342                 goto __CATCH;
3343
3344         *pValueLength = 0;
3345
3346         if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false) {
3347                 gCurMmsDecodeBuffPos--;
3348                 goto __CATCH;
3349         }
3350
3351         if (0x00 < oneByte && oneByte < 0x1F) {
3352                 /* short-length */
3353
3354                 *pValueLength = oneByte;
3355                 length = 1;
3356         } else if (oneByte == 0x1F) {
3357                 /* Length-quote = 0x1F */
3358
3359                 length = __MmsBinaryDecodeUintvar(pFile, &uintvar, totalLength);
3360                 if (length == -1) {
3361                         MSG_DEBUG("__MmsDecodeValueLength2: __MmsBinaryDecodeUintvar fail..\n");
3362                         goto __CATCH;
3363                 }
3364                 length ++;                                      // + length-quote
3365                 *pValueLength = uintvar;
3366         } else {
3367                 MSG_DEBUG("__MmsDecodeValueLength2: there is not length-quote, consider it as short length.\n");
3368                 *pValueLength = oneByte;
3369                 length = 1;
3370         }
3371
3372         return length;
3373
3374 __CATCH:
3375         MSG_DEBUG("__MmsDecodeValueLength2: getting data fail\n");
3376         return -1;
3377 }
3378
3379 /**
3380  * Decode QuotedString
3381  *
3382  * @param       pEncodedData    [in] QuotedString encoded data
3383  * @param       szBuff                  [out] Decoded quoted string
3384  * @param       bufLen                  [out] Buffer length
3385  * @return      length of quoted string
3386  */
3387 static int __MmsBinaryDecodeQuotedString(FILE *pFile, char *szBuff, int bufLen, int totalLength)
3388 {
3389         int iPos = 0;
3390         int length = 0;
3391         int readBytes = 0;
3392         char *pData = NULL;
3393         int returnLength = 0;
3394
3395         /*
3396          * Quoted-string = <Octet 34> *TEXT End-of-string
3397          * The TEXT encodes an RFC2616 Quoted-string with the enclosing quotation-marks <"> removed
3398          */
3399
3400         if (pFile == NULL || szBuff == NULL || bufLen <= 0)
3401                 return -1;
3402
3403         memset(szBuff, 0, bufLen);
3404
3405         if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
3406                                                                          gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
3407                 MSG_DEBUG("__MmsBinaryDecodeQuotedString: 1. fail to load to buffer \n");
3408                 goto __CATCH;
3409         }
3410
3411         length = strlen(gpCurMmsDecodeBuff) + 1;        // + NULL
3412
3413         if (length == 0)
3414                 goto __RETURN;
3415
3416         while (length > gMmsDecodeBufLen) {
3417                 if (gMmsDecodeBufLen <= 0) {
3418                         MSG_DEBUG("__MmsBinaryDecodeQuotedString: gMmsDecodeBufLen <= 0 \n");
3419                         MSG_DEBUG("__MmsBinaryDecodeQuotedString: %x %x %x %x %x\n",
3420                                                                                 gpCurMmsDecodeBuff[0], gpCurMmsDecodeBuff[1], gpCurMmsDecodeBuff[2],
3421                                                                                 gpCurMmsDecodeBuff[3], gpCurMmsDecodeBuff[4]);
3422                         MSG_DEBUG("__MmsBinaryDecodeQuotedString: %x %x %x %x %x\n",
3423                                                                                 gpCurMmsDecodeBuff[5], gpCurMmsDecodeBuff[6], gpCurMmsDecodeBuff[7],
3424                                                                                 gpCurMmsDecodeBuff[8], gpCurMmsDecodeBuff[9]);
3425                         MSG_DEBUG("__MmsBinaryDecodeQuotedString: %x %x %x %x %x\n",
3426                                                                                 gpCurMmsDecodeBuff[10], gpCurMmsDecodeBuff[11], gpCurMmsDecodeBuff[12],
3427                                                                                 gpCurMmsDecodeBuff[13], gpCurMmsDecodeBuff[14]);
3428                         MSG_DEBUG("__MmsBinaryDecodeQuotedString: %x %x %x %x %x\n",
3429                                                                                 gpCurMmsDecodeBuff[15], gpCurMmsDecodeBuff[16], gpCurMmsDecodeBuff[17],
3430                                                                                 gpCurMmsDecodeBuff[18], gpCurMmsDecodeBuff[19]);
3431                         goto __CATCH;
3432                 }
3433
3434                 pData = (char *)malloc(gMmsDecodeBufLen + 1);
3435                 if (pData == NULL)
3436                         goto __CATCH;
3437
3438                 memset(pData, 0, gMmsDecodeBufLen + 1);
3439
3440                 if (__MmsBinaryDecodeGetBytes(pFile, pData, gMmsDecodeBufLen, totalLength) == false)
3441                         goto __CATCH;
3442
3443                 returnLength += gMmsDecodeBufLen;
3444
3445                 if ((bufLen - iPos) > 0) {
3446                         readBytes = (gMmsDecodeBufLen < (bufLen - iPos)) ? gMmsDecodeBufLen : (bufLen - iPos);
3447                         if (iPos == 0 && (pData[0] == MARK)) {
3448                                 /* MARK: check first time only */
3449
3450                                 strncpy(szBuff + iPos, (char*)pData + 1, readBytes - 1);
3451                                 iPos += (readBytes - 1);
3452                         } else {
3453                                 strncpy(szBuff + iPos, (char*)pData, readBytes);
3454                                 iPos += readBytes;
3455                         }
3456                 }
3457
3458                 if (pData) {
3459                         free(pData);
3460                         pData = NULL;
3461                 }
3462
3463                 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
3464                                                                                 gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
3465                         MSG_DEBUG("__MmsBinaryDecodeText: 2. fail to load to buffer \n");
3466                         goto __CATCH;
3467                 }
3468                 length = strlen(gpCurMmsDecodeBuff) + 1;        // + NULL
3469         }       /* while */
3470
3471         if (length > 0) {
3472                 pData = (char *)malloc(length);
3473                 if (pData == NULL)
3474                         goto __CATCH;
3475
3476                 if (__MmsBinaryDecodeGetBytes(pFile, pData, length, totalLength) == false)
3477                         goto __CATCH;
3478
3479                 returnLength += length;
3480
3481                 if ((bufLen - iPos) > 0) {
3482                         /* read until NULL from raw data, and copy only string */
3483                         readBytes = (length < (bufLen - iPos)) ? length : (bufLen - iPos);
3484                         if (iPos == 0 && (pData[0] == MARK)) {
3485                                 /* MARK: check first time only */
3486                                 strncpy(szBuff + iPos, (char*)pData + 1, readBytes - 1);
3487                                 iPos += (readBytes - 1);
3488                         } else {
3489                                 strncpy(szBuff + iPos, (char*)pData, readBytes - 1);    // + NULL
3490                                 iPos += readBytes;
3491                         }
3492                 }
3493
3494                 if (pData) {
3495                         free(pData);
3496                         pData = NULL;
3497                 }
3498         }
3499
3500         szBuff[bufLen - 1] = '\0';
3501
3502         return returnLength;
3503
3504 __RETURN:
3505
3506         return length;
3507
3508 __CATCH:
3509
3510         if (pData) {
3511                 free(pData);
3512                 pData = NULL;
3513         }
3514
3515         return -1;
3516 }
3517
3518 /**
3519  * Decode Text
3520  *
3521  * @param       pEncodedData    [in] QuotedString encoded data
3522  * @param       szBuff                  [out] Decoded quoted string
3523  * @param       bufLen                  [out] Buffer length
3524  * @return      length of decode text string
3525  */
3526 static int __MmsBinaryDecodeText(FILE *pFile, char *szBuff, int bufLen, int totalLength)
3527 {
3528         int length = 0;
3529         int readBytes = 0;
3530         int iPos = 0;
3531         int returnLength = 0;
3532         char *pData = NULL;
3533         bool bQuote = false;
3534         int offset = 0;
3535
3536         /*
3537          * Text-String = [QUOTE]*TEXT end_of_string
3538          *                               [QUOTE]*(128~255)\0
3539          *                               *(32~126)\0
3540          */
3541
3542         if (pFile == NULL || szBuff == NULL || bufLen <= 0)
3543                 return -1;
3544
3545         offset = __MmsGetDecodeOffset();
3546         if (offset >= totalLength)
3547                 goto __RETURN;
3548
3549         memset(szBuff, 0, bufLen);
3550
3551         if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
3552                                                                         gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
3553                 MSG_DEBUG("__MmsBinaryDecodeText: 1. fail to load to buffer \n");
3554                 goto __CATCH;
3555         }
3556
3557         length = strlen(gpCurMmsDecodeBuff) + 1;        // + NULL
3558
3559         if (length == 0)
3560                 goto __RETURN;
3561
3562         while (length > gMmsDecodeBufLen) {
3563                 if (gMmsDecodeBufLen <= 0) {
3564                         MSG_DEBUG("__MmsBinaryDecodeQuotedString: gMmsDecodeBufLen <= 0 \n");
3565                         MSG_DEBUG("__MmsBinaryDecodeQuotedString: %x %x %x %x %x\n", gpCurMmsDecodeBuff[0], gpCurMmsDecodeBuff[1], gpCurMmsDecodeBuff[2],
3566                                                                                 gpCurMmsDecodeBuff[3], gpCurMmsDecodeBuff[4]);
3567                         MSG_DEBUG("__MmsBinaryDecodeQuotedString: %x %x %x %x %x\n", gpCurMmsDecodeBuff[5], gpCurMmsDecodeBuff[6], gpCurMmsDecodeBuff[7],
3568                                                                                 gpCurMmsDecodeBuff[8], gpCurMmsDecodeBuff[9]);
3569                         MSG_DEBUG("__MmsBinaryDecodeQuotedString: %x %x %x %x %x\n", gpCurMmsDecodeBuff[10], gpCurMmsDecodeBuff[11], gpCurMmsDecodeBuff[12],
3570                                                                                 gpCurMmsDecodeBuff[13], gpCurMmsDecodeBuff[14]);
3571                         MSG_DEBUG("__MmsBinaryDecodeQuotedString: %x %x %x %x %x\n", gpCurMmsDecodeBuff[15], gpCurMmsDecodeBuff[16], gpCurMmsDecodeBuff[17],
3572                                                                                 gpCurMmsDecodeBuff[18], gpCurMmsDecodeBuff[19]);
3573                         goto __CATCH;
3574                 }
3575
3576                 pData = (char *)malloc(gMmsDecodeBufLen + 1);
3577                 if (pData == NULL)
3578                         goto __CATCH;
3579
3580                 memset(pData, 0, gMmsDecodeBufLen + 1);
3581
3582                 if (__MmsBinaryDecodeGetBytes(pFile, pData, gMmsDecodeBufLen, totalLength) == false)
3583                         goto __CATCH;
3584
3585                 if ((bufLen - iPos) > 0) {
3586                         readBytes = (gMmsDecodeBufLen < (bufLen - iPos)) ? gMmsDecodeBufLen : (bufLen - iPos);
3587                         if (iPos == 0 && (pData[0] == QUOTE) && (bQuote == false)) {
3588                                 /* QUOTE: check first time only */
3589
3590                                 strncpy(szBuff + iPos, (char*)pData + 1, readBytes - 1);
3591                                 iPos += (readBytes - 1);
3592                                 bQuote = true;
3593                         } else {
3594                                 strncpy(szBuff + iPos, (char*)pData, readBytes);
3595                                 iPos += readBytes;
3596                         }
3597                 }
3598
3599                 if (pData) {
3600                         free(pData);
3601                         pData = NULL;
3602                 }
3603
3604                 returnLength += gMmsDecodeBufLen;
3605
3606                 if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
3607                                                                            gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
3608                         MSG_DEBUG("__MmsBinaryDecodeText: 2. fail to load to buffer \n");
3609                         goto __CATCH;
3610                 }
3611                 length = strlen(gpCurMmsDecodeBuff) + 1;        // + NULL
3612         }       /* while */
3613
3614         if (length > 0) {
3615                 pData = (char *)malloc(length);
3616                 if (pData == NULL)
3617                         goto __CATCH;
3618
3619                 memset(pData, 0, length);
3620
3621                 if (__MmsBinaryDecodeGetBytes(pFile, pData, length, totalLength) == false)
3622                         goto __CATCH;
3623
3624                 if ((bufLen - iPos) > 0) {
3625                         readBytes = (length < (bufLen - iPos)) ? length : (bufLen - iPos);
3626                         if (iPos == 0 && (pData[0] == QUOTE) && (bQuote == false)) {
3627                                 /* QUOTE: check first time only */
3628
3629                                 strncpy(szBuff + iPos, (char*)pData + 1, readBytes - 1);
3630                                 iPos += (readBytes - 1);
3631                                 bQuote = true;
3632                         } else {
3633                                 strncpy(szBuff + iPos, (char*)pData, readBytes - 1);    // + NULL
3634                                 iPos += readBytes;
3635                         }
3636                 }
3637
3638                 if (pData) {
3639                         free(pData);
3640                         pData = NULL;
3641                 }
3642
3643                 returnLength += length;         // + NULL
3644         }
3645
3646         szBuff[bufLen - 1] = '\0';
3647
3648         return returnLength;
3649
3650 __RETURN:
3651
3652         szBuff[0] = '\0';
3653         length = 0;
3654
3655         __MmsBinaryDecodeMovePointer(pFile, offset, totalLength);
3656
3657         return length;
3658
3659 __CATCH:
3660
3661         if (pData) {
3662                 free(pData);
3663                 pData = NULL;
3664         }
3665
3666         return -1;
3667 }
3668
3669 static char* __MmsBinaryDecodeText2(FILE *pFile, int totalLength, int *pLength)
3670 {
3671         int length = 0;
3672         int curLen = 0;
3673         char *pData = NULL;
3674         char *szBuff = NULL;
3675         char *szTempPtr = NULL;
3676         bool bQuote = false;
3677         int offset = 0;
3678
3679         /*
3680          * Text-String = [QUOTE]*TEXT end_of_string
3681          *                               [QUOTE]*(128~255)\0
3682          *                               *(32~126)\0
3683          */
3684
3685         if (pFile == NULL || pLength == NULL)
3686                 goto __CATCH;
3687
3688         *pLength = 0;
3689         offset = __MmsGetDecodeOffset();
3690         if (offset >= totalLength)
3691                 goto __RETURN;
3692
3693         if (__MsgLoadDataToDecodeBuffer(pFile, &gpCurMmsDecodeBuff, &gCurMmsDecodeBuffPos, &gMmsDecodeCurOffset,
3694                                                                    gpMmsDecodeBuf1, gpMmsDecodeBuf2, gMmsDecodeMaxLen, &gMmsDecodeBufLen, totalLength) == false) {
3695                 MSG_DEBUG("__MmsBinaryDecodeTextLen: 1. fail to load to buffer \n");
3696                 goto __CATCH;
3697         }
3698
3699         length = strlen(gpCurMmsDecodeBuff) + 1;
3700
3701         if (length == 0)
3702                 goto __CATCH;
3703
3704         while (length > gMmsDecodeBufLen) {
3705                 if (gMmsDecodeBufLen <= 0) {
3706                         MSG_DEBUG("__MmsBinaryDecodeQuotedString: gMmsDecodeBufLen <= 0 \n");
3707                         MSG_DEBUG("__MmsBinaryDecodeQuotedString: %x %x %x %x %x\n",
3708                                                                                 gpCurMmsDecodeBuff[0], gpCurMmsDecodeBuff[1], gpCurMmsDecodeBuff[2],
3709                                                                                 gpCurMmsDecodeBuff[3], gpCurMmsDecodeBuff[4]);
3710                         MSG_DEBUG("__MmsBinaryDecodeQuotedString: %x %x %x %x %x\n",
3711                                                                                 gpCurMmsDecodeBuff[5], gpCurMmsDecodeBuff[6], gpCurMmsDecodeBuff[7],
3712                                                                                 gpCurMmsDecodeBuff[8], gpCurMmsDecodeBuff[9]);
3713                         MSG_DEBUG("__MmsBinaryDecodeQuotedString: %x %x %x %x %x\n",
3714                                                                                 gpCurMmsDecodeBuff[10], gpCurMmsDecodeBuff[11], gpCurMmsDecodeBuff[12],
3715                                                                                 gpCurMmsDecodeBuff[13], gpCurMmsDecodeBuff[14]);
3716                         MSG_DEBUG("__MmsBinaryDecodeQuotedString: %x %x %x %x %x\n",
3717                                                                                 gpCurMmsDecodeBuff[15], gpCurMmsDecodeBuff[16], gpCurMmsDecodeBuff[17],
3718                                                                                 gpCurMmsDecodeBuff[18], gpCurMmsDecodeBuff[19]);
3719                         goto __CATCH;
3720                 }
3721
3722                 pData = (char *)malloc(gMmsDecodeBufLen + 1);
3723                 if (pData == NULL)
3724                         goto __CATCH;
3725
3726                 memset(pData, 0, gMmsDecodeBufLen + 1);
3727
3728                 if (__MmsBinaryDecodeGetBytes(pFile, pData, gMmsDecodeBufLen, totalLength) == false)
3729                         goto __CATCH;
3730
3731                 if (szBuff == NULL)     {
3732                         szBuff = (char *)malloc(gMmsDecodeBufLen + 1);
3733                 } else {
3734                         szTempPtr = (char *)realloc(szBuff, curLen + gMmsDecodeBufLen + 1);
3735
3736                         //NULL pointer check for realloc
3737                         if (szTempPtr == NULL) {
3738                                 goto __CATCH;
3739                         } else {
3740                                 szBuff = szTempPtr;
3741                         }
3742                 }
3743                 if (szBuff == NULL)
3744                         goto __CATCH;
3745
3746                 memset(szBuff + curLen, 0, gMmsDecodeBufLen + 1);
3747
3748                 if (curLen == 0 && (pData[0] == QUOTE) && (bQuote == false)) {
3749                         /* QUOTE: check first time only */
3750
3751                         strncpy(szBuff + curLen, (char*)pData + 1, gMmsDecodeBufLen - 1);
3752                         curLen += (gMmsDecodeBufLen - 1);
3753                         bQuote = true;
3754                 } else {
3755                         strncpy(szBuff + curLen, (char*)pData, gMmsDecodeBufLen);
3756                         curLen += gMmsDecodeBufLen;
3757                 }
3758
3759                 if (pData) {
3760                         free(pData);
3761                         pData = NULL;
3762                 }
3763
3764                 *pLength += gMmsDecodeBufLen;
3765
3766                 if (__MsgLoadDataToDecodeBuffer(pFile,
3767                                                            &gpCurMmsDecodeBuff,
3768                                                            &gCurMmsDecodeBuffPos,
3769                                                            &gMmsDecodeCurOffset,
3770                                                            gpMmsDecodeBuf1,
3771                                                            gpMmsDecodeBuf2,
3772                                                            gMmsDecodeMaxLen,
3773                                                            &gMmsDecodeBufLen,
3774                                                            totalLength) == false)
3775                 {
3776                         MSG_DEBUG("__MmsBinaryDecodeText: 2. fail to load to buffer \n");
3777                         goto __CATCH;
3778                 }
3779                 length = strlen(gpCurMmsDecodeBuff) + 1;
3780         }       /* while */
3781
3782         if (length > 0) {
3783                 pData = (char *)malloc(length);
3784                 if (pData == NULL) {
3785                         goto __CATCH;
3786                 }
3787
3788                 if (__MmsBinaryDecodeGetBytes(pFile, pData, length, totalLength) == false) {
3789                         goto __CATCH;
3790                 }
3791
3792                 if (szBuff == NULL) {
3793                         szBuff = (char *)malloc(length);
3794                 } else {
3795                         szTempPtr = (char *)realloc(szBuff, curLen + length);
3796
3797                         //NULL pointer check for realloc
3798                         if (szTempPtr == NULL)
3799                                 goto __CATCH;
3800                         else
3801                                 szBuff = szTempPtr;
3802                 }
3803
3804                 if (szBuff == NULL) {
3805                         goto __CATCH;
3806                 }
3807
3808                 memset(szBuff + curLen, 0, length);
3809
3810                 if (curLen == 0 && (pData[0] == QUOTE)  && (bQuote == false)) {
3811                         /* QUOTE: check first time only */
3812
3813                         strncpy(szBuff + curLen, (char*)pData + 1, length - 2);
3814                         curLen += (length - 1);
3815                         bQuote = true;
3816                 } else {
3817                         strncpy(szBuff + curLen, (char*)pData, length - 1);
3818                         curLen += length;
3819                 }
3820
3821                 if (pData) {
3822                         free(pData);
3823                         pData = NULL;
3824                 }
3825
3826                 *pLength += length;             // + NULL
3827         }
3828
3829         return szBuff;
3830
3831 __RETURN:
3832
3833         *pLength = 1;
3834
3835         __MmsBinaryDecodeMovePointer(pFile, offset, totalLength);
3836
3837         return szBuff;
3838
3839 __CATCH:
3840
3841         if (szBuff) {
3842                 free(szBuff);
3843                 szBuff = NULL;
3844         }
3845
3846         if (pData) {
3847                 free(pData);
3848                 pData = NULL;
3849         }
3850
3851         return NULL;
3852 }
3853
3854 /**
3855  * Decode Charset
3856  *
3857  * @param       pEncodedData    [in] QuotedString encoded data
3858  * @param       nCharSet                [out] Decoded character set
3859  * @return      length of charset value
3860  */
3861 static bool __MmsBinaryDecodeCharset(FILE *pFile, UINT32 *nCharSet, int *pCharSetLen, int totalLength)
3862 {
3863         UINT32 integer = 0;
3864
3865         /*
3866          * Charset v1.1 0x01 Well-known-charset
3867          *                                       Well-known-charset = Any-charset | Integer-value
3868          *                                              ; Both are encoded using values from
3869          *                                                Character Set Assignments table in Assigned Numbers
3870          *                                       Any-charset = <Octet 128>
3871          *                                              ; Equivalent to the special RFC2616 charset value ï¿½ï¿½*��
3872          */
3873
3874         if (pFile == NULL || nCharSet == NULL || pCharSetLen == NULL)
3875                 return false;
3876
3877         if (__MmsBinaryDecodeInteger(pFile, &integer, pCharSetLen, totalLength) == false) {
3878                 MSG_DEBUG("__MmsBinaryDecodeCharset : __MmsBinaryDecodeInteger fail...\n");
3879                 goto __CATCH;
3880         }
3881
3882         if (integer == 0) {
3883                 /* AnyCharSet : return MSG_CHARSET_UTF8 */
3884                 *nCharSet = MSG_CHARSET_UTF8;
3885                 return true;
3886         }
3887
3888         *nCharSet = MmsGetBinaryType(MmsCodeCharSet, (UINT16)integer);
3889
3890         if (*nCharSet == MIME_UNKNOWN) {
3891                 MSG_DEBUG("__MmsBinaryDecodeCharset : MmsGetBinaryType fail..\n");
3892                 *nCharSet = MSG_CHARSET_UNKNOWN;
3893         }
3894
3895         return true;
3896
3897 __CATCH:
3898         return false;
3899 }
3900
3901 /**
3902  * Decode EncodedString
3903  *
3904  * @param       pEncodedData    [in] QuotedString encoded data
3905  * @param       szBuff                  [out] Decoded string buffer
3906  * @param       bufLen                  [in]  Decoded buffer length
3907  * @return      length of decoded string length
3908  */
3909 static bool __MmsBinaryDecodeEncodedString(FILE *pFile, char *szBuff, int bufLen, int totalLength)
3910 {
3911         UINT32 valueLength = 0;
3912         UINT32 charSet = 0;
3913         int charSetLen = 0;
3914         int nTemp = 0;
3915         char *pData = NULL;
3916
3917         MSG_DEBUG("__MmsBinaryDecodeEncodedString: decode string..\n");
3918
3919         if (pFile == NULL || szBuff == NULL || bufLen <= 0) {
3920                 MSG_DEBUG("__MmsBinaryDecodeEncodedString: invalid file or buffer\n");
3921                 goto __CATCH;
3922         }
3923
3924         /*
3925          * Encoded_string_value = Text-string | Value-length Char-set Text-String
3926          *                                                Text-string    = [Quote]*TEXT End-of-string
3927          *                                                Value-length   = 0 ~ 31
3928          */
3929
3930         memset(szBuff, 0, bufLen);
3931
3932         switch (__MmsDecodeValueLength(pFile, &valueLength, totalLength)) {
3933         case -1:
3934                 goto __CATCH;
3935
3936         case 0:
3937
3938                 /* Text-string = [Quote]*TEXT End-of-string */
3939
3940                 if (__MmsBinaryDecodeText(pFile, szBuff, bufLen, totalLength) < 0) {
3941                         MSG_DEBUG("__MmsBinaryDecodeEncodedString : 1. __MmsBinaryDecodeText fail.\n");
3942                         goto __CATCH;
3943                 }
3944                 break;
3945
3946         default:
3947
3948                 /* Value-length Charset Text_string */
3949
3950                 if (__MmsBinaryDecodeCharset(pFile, &charSet, &charSetLen, totalLength) == false) {
3951                         MSG_DEBUG("__MmsBinaryDecodeEncodedString : __MmsBinaryDecodeCharset error\n");
3952                         goto __CATCH;                   /* (valueLength + valueLengthLen) */
3953                 }
3954
3955                 nTemp = __MmsBinaryDecodeText(pFile, szBuff, bufLen, totalLength);
3956                 if (nTemp < 0) {
3957                         /* There can be some error in data - no NULL -> try again with value length */
3958
3959                         pData = (char *)malloc(valueLength - charSetLen);
3960                         if (pData == NULL) {
3961                                 MSG_DEBUG("__MmsBinaryDecodeEncodedString : pData alloc fail.\n");
3962                                 goto __CATCH;
3963                         }
3964
3965                         if (__MmsBinaryDecodeGetLongBytes(pFile, pData, valueLength - charSetLen, totalLength) == false) {
3966                                 MSG_DEBUG("__MmsBinaryDecodeEncodedString : _MmsBinaryDecodeGetLongBytes fail.\n");
3967                                 goto __CATCH;
3968                         }
3969
3970                         strncpy(szBuff, pData, bufLen - 1);
3971                 }
3972
3973                 {//temp brace
3974
3975                         nTemp = strlen(szBuff);
3976
3977                         const char *pToCharSet = "UTF-8";
3978
3979                         UINT16 charset_code =  MmsGetBinaryValue(MmsCodeCharSet, charSet);
3980
3981                         const char *pFromCharSet = MmsPluginTextConvertGetCharSet(charset_code);
3982                         if (pFromCharSet == NULL || !strcmp(pFromCharSet, pToCharSet)) {
3983                                 if (pData) {
3984                                         free(pData);
3985                                         pData = NULL;
3986                                 }
3987                                 return true;
3988                         }
3989
3990                         char *pDest = NULL;
3991                         int destLen = 0;
3992
3993                         if (MmsPluginTextConvert(pToCharSet, pFromCharSet, szBuff, nTemp, &pDest, &destLen) == false) {
3994                                 MSG_DEBUG("MmsPluginTextConvert Fail");
3995
3996                         } else {
3997
3998                                 memset(szBuff, 0x00, bufLen);
3999                                 snprintf(szBuff, destLen, "%s", pDest);
4000                         }
4001                 }
4002         }
4003
4004         if (pData) {
4005                 free(pData);
4006                 pData = NULL;
4007         }
4008
4009         return true;
4010
4011 __CATCH:
4012
4013         if (pData) {
4014                 free(pData);
4015                 pData = NULL;
4016         }
4017
4018         return false;
4019 }
4020
4021
4022
4023 /**
4024  * Decode Encoded Addresses
4025  *
4026  * @param       pEncodedData    [in] QuotedString encoded data
4027  * @param       pAddrLength             [out] Decoded address length
4028  * @return      Decoded address list
4029  */
4030 MsgHeaderAddress *__MmsDecodeEncodedAddress(FILE *pFile, int totalLength)
4031 {
4032         UINT32 valueLength      = 0;
4033         UINT32 charSet          = 0;
4034         int charSetLen  = 0;
4035         int textLength  = 0;
4036         char *pAddrStr  = NULL;
4037         MsgHeaderAddress *pAddr = NULL;
4038
4039         MSG_DEBUG("__MmsDecodeEncodedAddress: decoding address..\n");
4040
4041         if (pFile == NULL) {
4042                 MSG_DEBUG("__MmsDecodeEncodedAddress: invalid file or buffer\n");
4043                 goto __CATCH;
4044         }
4045
4046         /*
4047          * Encoded_string_value = Text-string | Value-length Char-set Text-String
4048          *                                                Text-string    = [Quote]*TEXT End-of-string
4049          *                                                Value-length   = 0 ~ 31
4050          */
4051
4052         switch (__MmsDecodeValueLength(pFile, &valueLength, totalLength)) {
4053         case -1:
4054                 goto __CATCH;
4055
4056         case 0:
4057
4058                 /* Text-string = [Quote]*TEXT End-of-string */
4059
4060                 textLength = 0;
4061                 pAddrStr   = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
4062                 if (pAddrStr == NULL) {
4063                         MSG_DEBUG("__MmsDecodeEncodedAddress : 1. __MmsBinaryDecodeText2 fail.\n");
4064                         goto __CATCH;
4065                 }
4066                 break;
4067
4068         default:
4069
4070                 /* Value-length Charset Text_string */
4071
4072                 if (__MmsBinaryDecodeCharset(pFile, &charSet, &charSetLen, totalLength) == false) {
4073                         MSG_DEBUG("__MmsDecodeEncodedAddress : __MmsBinaryDecodeCharset error\n");
4074                         goto __CATCH;
4075                 }
4076
4077                 textLength = 0;
4078                 pAddrStr   = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
4079                 if (pAddrStr == NULL) {
4080                         /* There can be some error in data - no NULL -> try again with value length */
4081
4082                         pAddrStr = (char *)malloc(valueLength - charSetLen);
4083                         if (pAddrStr == NULL) {
4084                                 MSG_DEBUG("__MmsDecodeEncodedAddress : pData alloc fail.\n");
4085                                 goto __CATCH;
4086                         }
4087
4088                         if (__MmsBinaryDecodeGetLongBytes(pFile, pAddrStr, valueLength - charSetLen, totalLength) == false) {
4089                                 MSG_DEBUG("__MmsDecodeEncodedAddress : _MmsBinaryDecodeGetLongBytes fail.\n");
4090                                 goto __CATCH;
4091                         }
4092                 }
4093
4094                 /* fixme: charset transformation */
4095
4096                 break;
4097         }
4098
4099         pAddr = (MsgHeaderAddress *)malloc(sizeof(MsgHeaderAddress));
4100         if (pAddr == NULL)
4101                 goto __CATCH;
4102
4103         memset(pAddr, 0, sizeof(MsgHeaderAddress));
4104         pAddr->szAddr = pAddrStr;
4105
4106         return pAddr;
4107
4108 __CATCH:
4109
4110         if (pAddrStr) {
4111                 free(pAddrStr);
4112                 pAddrStr = NULL;
4113         }
4114
4115         return NULL;
4116 }
4117
4118
4119 /**
4120  * Decode Encoded Pointer String
4121  *
4122  * @param       pEncodedData    [in] Long integer encoded data
4123  * @param       pLongInteger    [out] Decoded long integer
4124  * @return      Decoded address list
4125  */
4126 static bool __MmsDecodeLongInteger(FILE *pFile, UINT32 *pLongInteger, int totalLength)
4127 {
4128         UINT8 oneByte = 0;
4129
4130         /*
4131          * Long-integer = Short-length Multi-octet-integer
4132          *                                Short-length = 0~30
4133          *                                Multi-octet-integer
4134          */
4135
4136         if (pFile == NULL || pLongInteger == NULL)
4137                 return false;
4138
4139         *pLongInteger = 0;
4140
4141         if (__MmsBinaryDecodeGetOneByte(pFile, &oneByte, totalLength) == false)
4142                 goto __CATCH;
4143
4144         if (oneByte > 31)
4145                 goto __CATCH;
4146
4147         *pLongInteger = __MmsHeaderDecodeIntegerByLength(pFile, oneByte, totalLength);
4148
4149         return true;
4150
4151 __CATCH:
4152         return false;
4153 }
4154
4155
4156 /*
4157  * @param       pEncodedData    [in] filename encoded data
4158  * @param       szBuff                  [out] filename output buffer
4159  * @param       fullLength              [in] full filename length
4160  * @param       bufLen                  [in] buffer length
4161  * CAUTION: bufLen - 1
4162  */
4163 static int __MmsDecodeGetFilename(FILE *pFile, char *szBuff, int bufLen, int totalLength)
4164 {
4165         char *pUTF8Buff = NULL;
4166         char *pLatinBuff = NULL;
4167         char *pExt = NULL;
4168         char *szSrc = NULL;
4169         char *szSrc2 = NULL;
4170         int length = 0;
4171         int textLength = 0;
4172
4173         char *pTmpBuff = NULL;
4174
4175         memset (szBuff, 0, bufLen);
4176
4177         textLength = 0;
4178         pLatinBuff  = __MmsBinaryDecodeText2(pFile, totalLength, &textLength);
4179
4180         //remove ""
4181         if (pLatinBuff) {
4182                 szSrc = MsgRemoveQuoteFromFilename(pLatinBuff);
4183                 if (szSrc) {
4184                         strcpy(pLatinBuff, szSrc);
4185                         free(szSrc);
4186                         szSrc = NULL;
4187                 }
4188
4189                 szSrc2 = MsgChangeHexString(pLatinBuff);
4190                 if (szSrc2) {
4191                         strcpy(pLatinBuff, szSrc2);
4192                         free(szSrc2);
4193                         szSrc2 = NULL;
4194                 }
4195
4196                 if (__MsgIsUTF8String((unsigned char*)pLatinBuff, strlen(pLatinBuff)) == false) {
4197                         length = strlen(pLatinBuff);
4198
4199                         int             utf8BufSize = 0;
4200                         utf8BufSize = __MsgGetLatin2UTFCodeSize((unsigned char*)pLatinBuff, length);
4201                         if (utf8BufSize < 3)
4202                                 utf8BufSize = 3;//min value
4203
4204                         pUTF8Buff = (char *)malloc(utf8BufSize + 1);
4205                         if (pUTF8Buff == NULL) {
4206                                 MSG_DEBUG("__MmsDecodeGetFilename: pUTF8Buff alloc fail \n");
4207                                 goto __CATCH;
4208                         }
4209
4210                         if (__MsgLatin2UTF ((unsigned char*)pUTF8Buff, utf8BufSize + 1, (unsigned char*)pLatinBuff, length) < 0) {
4211                                 MSG_DEBUG("__MmsDecodeGetFilename: MsgLatin2UTF fail \n");
4212                                 goto __CATCH;
4213                         }
4214                         free(pLatinBuff);
4215                         pLatinBuff = NULL;
4216                 } else {
4217                         pTmpBuff = MsgDecodeText(pLatinBuff);
4218                         pUTF8Buff = pTmpBuff;
4219                         free (pLatinBuff);
4220                         pLatinBuff = NULL;
4221                 }
4222         }
4223
4224         if (pUTF8Buff) {
4225                 /*
4226                  * keeping extension
4227                  * it should be kept extention even if the file name is shorten
4228                  */
4229
4230                 length = strlen(pUTF8Buff);
4231                 if ((pExt = strrchr(pUTF8Buff, '.')) != NULL) {
4232                         int nameLength  = 0;
4233                         nameLength = (length < bufLen) ? (length - strlen(pExt)) : (bufLen - strlen(pExt));
4234                         strncpy(szBuff, pUTF8Buff, nameLength);
4235                         strcat (szBuff, pExt);
4236                 } else {
4237                         strncpy(szBuff, pUTF8Buff, bufLen - 1);
4238                 }
4239                 free(pUTF8Buff);
4240                 pUTF8Buff = NULL;
4241
4242                 return textLength;
4243         }
4244
4245 __CATCH:
4246
4247         if (pLatinBuff) {
4248                 free(pLatinBuff);
4249                 pLatinBuff = NULL;
4250         }
4251
4252         if (pUTF8Buff) {
4253                 free(pUTF8Buff);
4254                 pUTF8Buff = NULL;
4255         }
4256
4257         return -1;
4258 }
4259
4260 /* ==========================================================
4261
4262            M  M  S        D  E  C  O  D  I  N  G
4263
4264    ==========================================================*/
4265
4266 //  to get message body this function should be modified from message raw file.
4267 bool MmsReadMsgBody(msg_message_id_t msgID, bool bSavePartsAsTempFiles, bool bRetrieved, char *retrievedPath)
4268 {
4269         FILE *pFile     = NULL;
4270         MmsMsg *pMsg = NULL;
4271         MsgMultipart *pMultipart = NULL;
4272         int nSize = 0;
4273         char szFullPath[MSG_FILEPATH_LEN_MAX] = {0, };
4274         char szTempMediaDir[MSG_FILEPATH_LEN_MAX] = {0, };
4275         int attachmax = MSG_ATTACH_MAX;
4276
4277         MSG_BEGIN();
4278         MSG_DEBUG("msg id : %d", msgID);
4279
4280         MmsPluginStorage::instance()->getMmsMessage(&pMsg);
4281         memset(pMsg, 0, sizeof(MmsMsg));
4282
4283         MmsInitHeader();
4284
4285         if (bRetrieved && (retrievedPath != NULL)) {
4286                 strncpy(szFullPath, retrievedPath, (strlen(retrievedPath) > MSG_FILEPATH_LEN_MAX ? MSG_FILEPATH_LEN_MAX:strlen(retrievedPath)));
4287         } else {
4288                 MmsPluginStorage::instance()->getMmsRawFilePath(msgID, szFullPath);
4289         }
4290
4291         pMsg->msgID = msgID;
4292
4293         /*      read from MMS raw file  */
4294         strncpy(pMsg->szFileName, szFullPath + strlen(MSG_DATA_PATH), strlen(szFullPath + strlen(MSG_DATA_PATH)));
4295
4296         MSG_DEBUG("szFullPath = (%s)", szFullPath);
4297
4298         if (MsgGetFileSize(szFullPath, &nSize) == false) {
4299                 MSG_DEBUG("MsgGetFileSize: failed");
4300                 goto __CATCH;
4301         }
4302
4303         pFile = MsgOpenFile(szFullPath, "rb");
4304
4305         if (pFile == NULL) {
4306                 MSG_DEBUG("_MmsReadMsgBody: invalid mailbox\n");
4307                 goto __CATCH;
4308         }
4309
4310         MmsRegisterDecodeBuffer();
4311
4312         if (MmsBinaryDecodeMsgHeader(pFile, nSize) == false) {
4313                 MSG_DEBUG("_MmsReadMsgBody: MmsBinaryDecodeMsgHeader fail...\n");
4314                 goto __CATCH;
4315         }
4316
4317 #ifdef  __SUPPORT_DRM__
4318         if (MmsDrm2GetConvertState() != MMS_DRM2_CONVERT_FINISH)
4319                 MmsDrm2SetConvertState(MMS_DRM2_CONVERT_NONE);  //initialize convertState
4320 #endif
4321
4322         if (MmsBinaryDecodeMsgBody(pFile, szFullPath, nSize) == false) {
4323                 MSG_DEBUG("_MmsReadMsgBody: MmsBinaryDecodeMsgBody fail\n");
4324                 goto __CATCH;
4325         }
4326
4327 #ifdef  __SUPPORT_DRM__
4328         if (MmsDrm2GetConvertState() == MMS_DRM2_CONVERT_REQUIRED) {
4329                 MSG_DEBUG("_MmsReadMsgBody: MmsDrm2GetConvertState returns MMS_DRM2_CONVERT_REQUIRED.\n");
4330                 goto RETURN;
4331         }
4332 #endif
4333
4334         /* Set mmsHeader.msgType & msgBody to pMsg ----------- */
4335
4336         memcpy(&(pMsg->msgType), &(mmsHeader.msgType), sizeof(MsgType));
4337         memcpy(&(pMsg->msgBody), &(mmsHeader.msgBody), sizeof(MsgBody));
4338
4339 {//attribute convert mmsHeader -> mmsAttribute
4340
4341         pMsg->mmsAttrib.contentType = (MimeType)mmsHeader.msgType.type;
4342
4343         pMsg->mmsAttrib.date = mmsHeader.date;
4344
4345         if (mmsHeader.deliveryReport == MMS_REPORT_YES) {
4346                 pMsg->mmsAttrib.bAskDeliveryReport = true;
4347         }
4348
4349         memcpy(&pMsg->mmsAttrib.deliveryTime, &mmsHeader.deliveryTime, sizeof(MmsTimeStruct));
4350
4351         memcpy(&pMsg->mmsAttrib.expiryTime, &mmsHeader.expiryTime, sizeof(MmsTimeStruct));
4352
4353         pMsg->mmsAttrib.msgClass = mmsHeader.msgClass;
4354
4355         snprintf(pMsg->szMsgID, sizeof(pMsg->szMsgID), "%s", mmsHeader.szMsgID);
4356
4357         pMsg->mmsAttrib.msgType = mmsHeader.type;
4358
4359         pMsg->mmsAttrib.version = mmsHeader.version;
4360
4361         pMsg->mmsAttrib.msgSize = mmsHeader.msgSize;
4362
4363         pMsg->mmsAttrib.priority = mmsHeader.priority;
4364
4365         if (mmsHeader.readReply == MMS_REPORT_YES) {
4366                 pMsg->mmsAttrib.bAskReadReply = true;
4367         }
4368
4369         snprintf(pMsg->mmsAttrib.szSubject, sizeof(pMsg->mmsAttrib.szSubject), "%s", mmsHeader.szSubject);
4370
4371         snprintf(pMsg->szTrID, sizeof(pMsg->szTrID), "%s", mmsHeader.szTrID);
4372
4373         pMsg->mmsAttrib.retrieveStatus = mmsHeader.retrieveStatus;
4374
4375         //FIXME:: mmsHeader will release after delete global mmsHeader
4376         //memset(&(mmsHeader.msgBody), 0x00, sizeof(MsgBody));//After copy to MmsMsg
4377 }
4378         if (pMsg->msgBody.pPresentationBody) {
4379                 if(MsgFseek(pFile, pMsg->msgBody.pPresentationBody->offset, SEEK_SET) < 0)
4380                         goto __CATCH;
4381
4382                 pMsg->msgBody.pPresentationBody->body.pText = (char *)malloc(pMsg->msgBody.pPresentationBody->size + 1);
4383                 if (pMsg->msgBody.pPresentationBody->body.pText == NULL)
4384                         goto __CATCH;
4385
4386                 memset(pMsg->msgBody.pPresentationBody->body.pText, 0, pMsg->msgBody.pPresentationBody->size + 1);
4387
4388                 ULONG nRead = 0;
4389                 nRead = MsgReadFile(pMsg->msgBody.pPresentationBody->body.pText, sizeof(char), pMsg->msgBody.pPresentationBody->size, pFile);
4390                 if (nRead == 0)
4391                         goto __CATCH;
4392
4393         }
4394
4395         MsgCloseFile(pFile);
4396         pFile = NULL;
4397
4398         /* nPartCount */
4399         pMsg->nPartCount = 0;
4400
4401         if (MsgIsMultipart(mmsHeader.msgType.type) == true) {
4402                 pMultipart = pMsg->msgBody.body.pMultipart;
4403                 while (pMultipart) {
4404                         pMsg->nPartCount++;
4405
4406                         if (pMultipart->type.type == MIME_TEXT_PLAIN)
4407                                 attachmax++;
4408
4409                         if ((mmsHeader.msgType.type == MIME_APPLICATION_VND_WAP_MULTIPART_MIXED)||(mmsHeader.msgType.type == MIME_MULTIPART_MIXED)) {
4410                                 if ((pMsg->nPartCount >= attachmax)&&(pMultipart->pNext != NULL)) {
4411                                         MmsReleaseMsgBody(pMultipart->pNext->pBody, pMultipart->pNext->type.type);
4412
4413                                         free(pMultipart->pNext->pBody);
4414                                         pMultipart->pNext->pBody= NULL;
4415
4416                                         free(pMultipart->pNext);
4417
4418                                         pMultipart->pNext = NULL;
4419                                         break;
4420                                 }
4421                         }
4422                         pMultipart = pMultipart->pNext;
4423                 }
4424         } else {
4425                 if (pMsg->msgBody.size > 0)
4426                         pMsg->nPartCount++;
4427         }
4428
4429         /*      make temporary  */
4430         snprintf(szTempMediaDir, MSG_FILEPATH_LEN_MAX, MSG_DATA_PATH"%s.dir", pMsg->szFileName);
4431
4432         if (MsgIsMultipart(pMsg->msgType.type) == true) {
4433                 int partIndex = 0;
4434                 pMultipart = pMsg->msgBody.body.pMultipart;
4435
4436                 if (bSavePartsAsTempFiles) {
4437                         if (mkdir(szTempMediaDir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) < 0) {
4438                                 if (errno == EEXIST) {
4439                                         MSG_DEBUG("The %s already exists", szTempMediaDir);
4440                                 } else {
4441                                         MSG_DEBUG("Fail to Create Dir [%s]", szTempMediaDir);
4442                                         goto __CATCH;
4443                                 }
4444                         }
4445                 }
4446
4447                 if (pMsg->msgBody.pPresentationBody) {
4448                         if (__MmsMultipartSaveAsTempFile(&pMsg->msgBody.presentationType, pMsg->msgBody.pPresentationBody,
4449                                                                                                 (char*)MSG_DATA_PATH, pMsg->szFileName, 0, bSavePartsAsTempFiles) == false)
4450                                 goto __CATCH;
4451                 }
4452
4453                 while (pMultipart) {
4454
4455                         if (__MmsMultipartSaveAsTempFile(&pMultipart->type, pMultipart->pBody,
4456                                                                                         (char*)MSG_DATA_PATH, pMsg->szFileName, partIndex, bSavePartsAsTempFiles) == false)
4457                                 goto __CATCH;
4458
4459                         pMultipart = pMultipart->pNext;
4460                         partIndex ++;
4461                 }
4462
4463         } else { //single part
4464                 if (pMsg->nPartCount > 0) {
4465
4466                         if (bSavePartsAsTempFiles) {
4467                                 if (mkdir(szTempMediaDir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) < 0) {
4468                                         if (errno == EEXIST) {
4469                                                 MSG_DEBUG("The %s already exists", szTempMediaDir);
4470                                         } else {
4471                                                 MSG_DEBUG("Fail to Create Dir [%s]", szTempMediaDir);
4472                                                 goto __CATCH;
4473                                         }
4474                                 }
4475                         }
4476
4477                         if (__MmsMultipartSaveAsTempFile( &pMsg->msgType, &pMsg->msgBody,
4478                                                                                         (char*)MSG_DATA_PATH, pMsg->szFileName, 0, bSavePartsAsTempFiles) == false)
4479                                 goto __CATCH;
4480                 }
4481         }
4482         MSG_DEBUG("****   _MmsReadMsgBody:  E  N  D   (Success)  ***\n");
4483         return true;
4484
4485 #ifdef  __SUPPORT_DRM__
4486
4487 RETURN:
4488
4489         if (pFile != NULL) {
4490                 MsgCloseFile(pFile);
4491                 pFile = NULL;
4492         }
4493
4494         return false;
4495
4496 #endif
4497
4498 __CATCH:
4499
4500         MmsInitHeader();
4501         MmsUnregisterDecodeBuffer();
4502
4503         if (pFile != NULL) {
4504                 MsgCloseFile(pFile);
4505                 pFile = NULL;
4506         }
4507
4508 #ifdef __SUPPORT_DRM__
4509         MmsReleaseMsgDRMInfo(&pMsg->msgType.drmInfo);
4510 #endif
4511
4512         MmsReleaseMsgBody(&pMsg->msgBody, pMsg->msgType.type);
4513         MSG_DEBUG("_MmsReadMsgBody:    E  N  D    (fail)    ******************** \n");
4514
4515         return false;
4516 }
4517
4518 static bool __MsgFreeHeaderAddress(MsgHeaderAddress *pAddr)
4519 {
4520         MsgHeaderAddress *pTempAddr = NULL;
4521
4522         while (pAddr != NULL) {
4523                 pTempAddr = pAddr;
4524                 pAddr = pAddr->pNext;
4525
4526                 if (pTempAddr->szAddr) {
4527                         free(pTempAddr->szAddr);
4528                         pTempAddr->szAddr = NULL;
4529                 }
4530
4531                 free(pTempAddr);
4532                 pTempAddr = NULL;
4533         }
4534
4535         return true;
4536 }
4537
4538 static bool __MsgCheckFileNameHasInvalidChar(char *szName)
4539 {
4540         int     strLen = 0;
4541         int i = 0;
4542
4543         strLen = strlen(szName);
4544
4545         for (i=0; i<strLen; i++) {
4546                 if (__MsgIsInvalidFileNameChar(szName[i]))
4547                         return true;
4548         }
4549
4550         return false;
4551 }
4552
4553 static bool __MsgReplaceInvalidFileNameChar(char *szInText, char replaceChar)
4554 {
4555         int nCount = 0;
4556         int totalLength = 0;
4557
4558         totalLength = strlen(szInText);
4559
4560         while ((*(szInText+nCount) != '\0') && (nCount < totalLength)) {
4561                 if (0x0001 <= *(szInText+nCount) && *(szInText+nCount) <= 0x007F) {
4562                         if (__MsgIsInvalidFileNameChar(szInText[nCount]))
4563                                 *(szInText+nCount) = replaceChar;
4564
4565                         nCount += 1;
4566                 } else {
4567                         nCount += 2;
4568                 }
4569         }
4570
4571         return true;
4572 }
4573
4574 static char *__MsgGetStringUntilDelimiter(char *pszString, char delimiter)
4575 {
4576         char *pszBuffer = NULL;
4577         char *pszStrDelimiter = NULL;
4578         int     bufLength = 0;
4579
4580         if (!pszString) {
4581                 MSG_DEBUG("_MsgGetStringUntilDelimiter: pszString == NULL \n");
4582                 return NULL;
4583         }
4584
4585         if ((pszStrDelimiter = strchr(pszString, delimiter)) == NULL) {
4586                 MSG_DEBUG("_MsgGetStringUntilDelimiter: There is no %c in %s. \n", delimiter, pszString);
4587                 return NULL;
4588         }
4589
4590         bufLength = pszStrDelimiter - pszString;
4591
4592         if ((pszBuffer = (char*)malloc (bufLength + 1)) == NULL) {
4593                 MSG_DEBUG("malloc is failed");
4594                 return NULL;
4595         }
4596         memset(pszBuffer, 0, bufLength + 1) ;
4597
4598         strncat(pszBuffer, pszString, bufLength);
4599
4600         return pszBuffer;
4601 }
4602
4603 char *MsgChangeHexString(char *pOrg)
4604 {
4605         char *pNew = NULL;
4606         char szBuf[10] = {0,};
4607         char OneChar;
4608         int cLen = 0;
4609         int cIndex =0;
4610         int index = 0;
4611
4612         if (pOrg == NULL)
4613                 return false;
4614
4615         cLen = strlen(pOrg);
4616
4617         pNew = (char *)malloc(cLen + 1);
4618         if (pNew == NULL)
4619                 return NULL;
4620
4621         memset(pNew, 0, cLen + 1);
4622
4623         for (cIndex = 0; cIndex< cLen ; cIndex++) {
4624                 if (pOrg[cIndex] == '%') {
4625                         if (pOrg[cIndex+1] != 0 && pOrg[cIndex+2] != 0)         {
4626                                 snprintf(szBuf, sizeof(szBuf), "%c%c", pOrg[cIndex+1], pOrg[cIndex+2]); // read two chars after '%'
4627
4628                                 if (__MsgIsHexChar(szBuf) == true) { // check the two character is between  0 ~ F
4629                                         OneChar = __MsgConvertHexValue(szBuf);
4630
4631                                         pNew[index] = OneChar;
4632                                         index++;
4633                                         cIndex+= 2;
4634                                         continue;
4635                                 }
4636                         }
4637                 }
4638                 pNew[index++] = pOrg[cIndex];
4639         }
4640         return pNew;
4641 }
4642
4643 static bool __MsgParseParameter(MsgType *pType, char *pSrc)
4644 {
4645         char *pName = NULL;
4646         char *pValue = NULL;
4647         char *pDec = NULL;
4648         char *pTest = NULL;
4649         char *pNextParam = NULL;
4650         char *pExt = NULL;
4651         int nameLen = 0;
4652         int count;
4653         char *pTempNextParam = NULL;
4654         char *pCh = NULL;
4655         char *szSrc = NULL;
4656         char *pUTF8Buff = NULL;
4657
4658         while (pSrc != NULL) {
4659                 pSrc = __MsgSkipWS(pSrc);
4660                 if (pSrc == NULL) {
4661                         /* End of parse parameter */
4662                         return true;
4663                 }
4664
4665                 pNextParam = NULL;
4666                 pTempNextParam = strchr(pSrc, MSG_CH_SEMICOLON);
4667                 pCh = pSrc;
4668
4669                 if (*pCh == MSG_CH_QUOT) {
4670                         count = 1;
4671                 } else {
4672                         count = 0;
4673                 }
4674
4675                 pCh++;
4676                 for (; pCh<=pTempNextParam ; pCh++) {
4677                         if (*pCh == MSG_CH_QUOT)
4678                                 if (*(pCh - 1) != '\\')
4679                                         count++;
4680                 }
4681
4682                 if (count%2 == 0)
4683                         pNextParam = pTempNextParam;
4684
4685                 if (pNextParam)
4686                         *pNextParam++ = MSG_CH_NULL;
4687
4688                 if ((pName = strchr(pSrc, MSG_CH_EQUAL)) != NULL) {
4689                         *pName++ = MSG_CH_NULL;
4690
4691                         if ((pValue = strchr(pName, MSG_CH_QUOT))!= NULL) {
4692                                 *pValue++ = MSG_CH_NULL;
4693
4694                                 if ((pTest = strchr(pValue, MSG_CH_QUOT)) != NULL)
4695                                         *pTest = MSG_CH_NULL;
4696
4697                                 pDec = MsgDecodeText(pValue);           // Api is to long, consider Add to another file (MsgMIMECodec.c)
4698                         } else {
4699                                 pDec = MsgDecodeText(pName);
4700                         }
4701
4702                         switch (_MsgGetCode(MSG_PARAM, pSrc)) {
4703                         case MSG_PARAM_BOUNDARY:
4704
4705                                 /* RFC 822: boundary := 0*69<bchars> bcharsnospace */
4706
4707                                 memset (pType->param.szBoundary, 0, MSG_BOUNDARY_LEN + 1);
4708                                 strncpy(pType->param.szBoundary, pDec, MSG_BOUNDARY_LEN);
4709                                 MSG_DEBUG("_MsgParseParameter: szBoundary = %s \n", pType->param.szBoundary);
4710                                 break;
4711
4712                         case MSG_PARAM_CHARSET:
4713                                 pType->param.charset = _MsgGetCode(MSG_CHARSET, pDec);
4714
4715                                 if (pType->param.charset == INVALID_HOBJ)
4716                                         pType->param.charset = MSG_CHARSET_UNKNOWN;
4717
4718                                 MSG_DEBUG("_MsgParseParameter: type = %d    [charset] = %d \n", pType->type, pType->param.charset);
4719                                 break;
4720
4721                         case MSG_PARAM_NAME:
4722
4723                                 memset (pType->param.szName, 0, MSG_LOCALE_FILENAME_LEN_MAX + 1);
4724
4725                                 pUTF8Buff = __MsgConvertLatin2UTF8FileName(pDec);
4726
4727                                 if (pUTF8Buff) {
4728                                         if ((pExt = strrchr(pUTF8Buff, '.')) != NULL) {
4729                                                 if ((MSG_LOCALE_FILENAME_LEN_MAX-1) < strlen(pUTF8Buff)) {
4730                                                         nameLen = (MSG_LOCALE_FILENAME_LEN_MAX-1) - strlen(pExt);
4731                                                 } else {
4732                                                         nameLen = strlen(pUTF8Buff) - strlen(pExt);
4733                                                 }
4734
4735                                                 strncpy(pType->param.szName, pUTF8Buff, nameLen);
4736                                                 strcat (pType->param.szName, pExt);
4737                                         } else {
4738                                                 strncpy(pType->param.szName, pUTF8Buff, (MSG_LOCALE_FILENAME_LEN_MAX-1));
4739                                         }
4740                                         free(pUTF8Buff);
4741                                         pUTF8Buff = NULL;
4742
4743                                         if (__MsgChangeSpace(pType->param.szName, &szSrc) == true) {
4744                                                 if (szSrc)
4745                                                         strncpy(pType->param.szName, szSrc , strlen(szSrc));
4746                                         }
4747
4748                                         if (szSrc) {
4749                                                 free(szSrc);
4750                                                 szSrc = NULL;
4751                                         }
4752
4753                                         // Remvoe '/', ex) Content-Type: image/gif; name="images/vf7.gif"
4754                                         __MsgRemoveFilePath(pType->param.szName);
4755                                 } else {
4756                                         MSG_DEBUG("_MsgParseParameter: MsgConvertLatin2UTF8FileName(%s) return NULL\n", pDec);
4757                                 }
4758
4759                                 MSG_DEBUG("_MsgParseParameter: szName = %s \n", pType->param.szName);
4760                                 break;
4761
4762                         case MSG_PARAM_FILENAME:
4763
4764                                 memset (pType->param.szFileName, 0, MSG_FILENAME_LEN_MAX+1);
4765
4766                                 pUTF8Buff = __MsgConvertLatin2UTF8FileName(pDec);
4767
4768                                 if (pUTF8Buff) {
4769                                         if ((pExt = strrchr(pUTF8Buff, '.')) != NULL) {
4770                                                 if ((MSG_FILENAME_LEN_MAX-1) < strlen(pUTF8Buff)) {
4771                                                         nameLen = (MSG_FILENAME_LEN_MAX-1) - strlen(pExt);
4772                                                 } else {
4773                                                         nameLen = strlen(pUTF8Buff) - strlen(pExt);
4774                                                 }
4775
4776                                                 strncpy(pType->param.szFileName, pUTF8Buff, nameLen);
4777                                                 strcat (pType->param.szFileName, pExt);
4778                                         } else {
4779                                                 strncpy(pType->param.szFileName, pUTF8Buff, (MSG_FILENAME_LEN_MAX-1));
4780                                         }
4781                                         free(pUTF8Buff);
4782                                         pUTF8Buff = NULL;
4783
4784                                         if (__MsgChangeSpace(pType->param.szFileName, &szSrc) == true)
4785                                                 strcpy(pType->param.szFileName, szSrc);
4786
4787                                         if (szSrc) {
4788                                                 free(szSrc);
4789                                                 szSrc = NULL;
4790                                         }
4791
4792                                         // Remvoe '/', ex) Content-Type: image/gif; name="images/vf7.gif"
4793                                         __MsgRemoveFilePath(pType->param.szFileName);
4794                                 } else {
4795                                         MSG_DEBUG("_MsgParseParameter: MsgConvertLatin2UTF8FileName(%s) return NULL\n", pDec);
4796                                 }
4797
4798                                 MSG_DEBUG("_MsgParseParameter: szFileName = %s \n", pType->param.szFileName);
4799
4800                                 break;
4801
4802                         case MSG_PARAM_TYPE:
4803
4804                                 /* type/subtype of root. Only if content-type is multipart/related */
4805
4806                                 pType->param.type = _MsgGetCode(MSG_TYPE, pDec);
4807                                 MSG_DEBUG("_MsgParseParameter: type = %d \n", pType->param.type);
4808
4809                                 break;
4810
4811                         case MSG_PARAM_START:
4812
4813                                 /* Content-id. Only if content-type is multipart/related */
4814
4815                                 memset (pType->param.szStart, 0, MSG_MSG_ID_LEN + 1);
4816                                 strncpy(pType->param.szStart, pDec, MSG_MSG_ID_LEN);
4817
4818                                 MSG_DEBUG("_MsgParseParameter: szStart = %s \n", pType->param.szStart);
4819
4820                                 break;
4821
4822                         case MSG_PARAM_START_INFO :
4823
4824                                 /* Only if content-type is multipart/related */
4825
4826                                 memset (pType->param.szStartInfo, 0, MSG_MSG_ID_LEN + 1);
4827                                 strncpy(pType->param.szStartInfo, pDec, MSG_MSG_ID_LEN);
4828
4829                                 MSG_DEBUG("_MsgParseParameter: szStartInfo = %s \n", pType->param.szStartInfo);
4830
4831                                 break;
4832
4833                         case MSG_PARAM_REPORT_TYPE :
4834
4835                                 //  only used as parameter of Content-Type: multipart/report; report-type=delivery-status;
4836
4837                                 if (pDec != NULL && strcasecmp(pDec, "delivery-status") == 0) {
4838                                         pType->param.reportType = MSG_PARAM_REPORT_TYPE_DELIVERY_STATUS;
4839                                 } else {
4840                                         pType->param.reportType = MSG_PARAM_REPORT_TYPE_UNKNOWN;
4841                                 }
4842
4843                                 MSG_DEBUG("_MsgParseParameter: reportType = %s \n", pDec);
4844                                 break;
4845
4846                         default:
4847
4848                                 MSG_DEBUG("_MsgParseParameter: Unknown paremeter (%s)\n", pDec);
4849                                 break;
4850                         }
4851
4852                         if (pDec) {
4853                                 free(pDec);
4854                                 pDec = NULL;
4855                         }
4856                 }
4857                 pSrc = pNextParam;
4858         }
4859         return true;
4860 }
4861
4862 static char *__MsgSkipWS(char *s)
4863 {
4864         while (true) {
4865                 if ((*s == MSG_CH_CR) || (*s == MSG_CH_LF) || (*s == MSG_CH_SP) || (*s == MSG_CH_TAB)) {
4866                         ++s;
4867                 } else if ((*s != '(') || (__MsgSkipComment(s,(long)NULL)==NULL)) {
4868                         return s;
4869                 }
4870         }
4871 }
4872
4873 static char *__MsgSkipComment (char *s,long trim)
4874 {
4875
4876         char *ret;
4877         char *s1 = s;
4878         char *t = NULL;
4879
4880         // ignore empty space
4881         for (ret = ++s1; *ret == ' '; ret++)
4882                 ;
4883
4884         // handle '(', ')', '\',  '\0'
4885         do {
4886                 switch (*s1) {
4887                 case '(':
4888                         if (!__MsgSkipComment (s1,(long)NULL))
4889                                 return NULL;
4890                         t = --s1;
4891                         break;
4892                 case ')':
4893                         s = ++s1;
4894                         if (trim) {
4895                                 if (t) {
4896                                         t[1] = '\0';
4897                                 } else {
4898                                         *ret = '\0';
4899                                 }
4900                         }
4901                         return ret;
4902                 case '\\':
4903                         if (*++s1)
4904                                 break;
4905                 case '\0':
4906                         *s = '\0';
4907                         return NULL;
4908                 case ' ':
4909                         break;
4910                 default:
4911                         t = s1;
4912                         break;
4913                 }
4914         }while (s1++);
4915
4916         /* DEADCODE
4917         return NULL;
4918         */
4919 }
4920
4921 static char *__MsgConvertLatin2UTF8FileName(char *pSrc)
4922 {
4923         char *pUTF8Buff  = NULL;
4924         char *pData = NULL;
4925
4926
4927         //convert utf8 string
4928         if (__MsgIsUTF8String((unsigned char*)pSrc, strlen(pSrc)) == false) {
4929                 int length  = 0;
4930                 int utf8BufSize = 0;
4931
4932                 length = strlen(pSrc);
4933                 utf8BufSize = __MsgGetLatin2UTFCodeSize((unsigned char*)pSrc, length);
4934                 if (utf8BufSize < 3)
4935                         utf8BufSize = 3; //min value
4936
4937                 pUTF8Buff = (char *)malloc(utf8BufSize + 1);
4938
4939                 if (pUTF8Buff == NULL) {
4940                         MSG_DEBUG("MsgConvertLatin2UTF8FileName: pUTF8Buff alloc fail \n");
4941                         goto __CATCH;
4942                 }
4943
4944                 if (__MsgLatin2UTF ((unsigned char*)pUTF8Buff, utf8BufSize + 1, (unsigned char*)pSrc, length) < 0) {
4945                         MSG_DEBUG("MsgConvertLatin2UTF8FileName: MsgLatin2UTF fail \n");
4946                         goto __CATCH;
4947                 }
4948         } else {
4949                 int length = strlen(pSrc);
4950                 pUTF8Buff = (char *)calloc(1, length+1);
4951
4952                 if (pUTF8Buff == NULL) {
4953                         MSG_DEBUG("MsgConvertLatin2UTF8FileName: pUTF8Buff alloc fail \n");
4954                         goto __CATCH;
4955                 }
4956
4957                 memcpy(pUTF8Buff, pSrc, length);
4958         }
4959
4960         //convert hex string
4961         if (__MsgIsPercentSign(pUTF8Buff) == true) {
4962                 pData = MsgChangeHexString(pUTF8Buff);
4963                 if (pData) {
4964                         strcpy(pUTF8Buff, pData);
4965                         free(pData);
4966                         pData = NULL;
4967                 }
4968         }
4969
4970         return pUTF8Buff;
4971
4972 __CATCH:
4973
4974         if (pUTF8Buff) {
4975                 free(pUTF8Buff);
4976                 pUTF8Buff = NULL;
4977         }
4978
4979         return NULL;
4980 }
4981
4982 static bool __MsgChangeSpace(char *pOrg, char **ppNew)
4983 {
4984         char *pNew = NULL;
4985         int cLen = 0;
4986         int cIndex =0;
4987         int index = 0;
4988
4989         if (pOrg == NULL)
4990                 return false;
4991
4992         cLen = strlen(pOrg);
4993
4994         pNew = (char *)malloc(cLen + 1);
4995         if (pNew == NULL)
4996                 return false;
4997
4998         memset(pNew, 0, cLen + 1);
4999
5000         for (cIndex=0; cIndex<cLen;cIndex++) {
5001                 if (pOrg[cIndex] == '%' && pOrg[cIndex+1] == '2' && pOrg[cIndex+2] == '0') {
5002                         pNew[index] = ' ';
5003                         index++;
5004                         cIndex+= 2;
5005                         continue;
5006                 }
5007                 pNew[index++] = pOrg[cIndex];
5008         }
5009
5010         *ppNew = pNew;
5011
5012         return true;
5013 }
5014
5015 static void __MsgRemoveFilePath(char *pSrc)
5016 {
5017         // Remvoe '/', ex) Content-Type: image/gif; name="images/vf7.gif"
5018         char *pPath = NULL;
5019         char *pTemp = NULL;
5020         char szFileName[MSG_FILENAME_LEN_MAX] = {0};
5021
5022         if (pSrc == NULL)
5023                 return;
5024
5025         pTemp = pSrc;
5026         while ((pTemp = strchr(pTemp, '/')) != NULL) {
5027                 // Find the last  '/'
5028                 pPath = pTemp;
5029                 pTemp++;
5030         }
5031
5032         if (pPath) {
5033                 MSG_DEBUG("_MsgRemoveFilePath: filename(%s)\n", pSrc);
5034
5035                 // case : images/vf7.gif -> vf7.gif
5036                 if (pPath != NULL && *(pPath+1) != '\0') {
5037                         strncpy(szFileName, pPath+1, strlen(pPath+1));
5038                         strncpy(pSrc, szFileName , strlen(szFileName));
5039                 }
5040         }
5041         // Remove additional file information
5042         // ex) Content-type: application/octet-stream; name="060728gibson_210.jpg?size=s"
5043         // if "?size=" exist, insert NULL char.
5044         {
5045                 pTemp = strcasestr(pSrc, "?size=");
5046                 if (pTemp != NULL)
5047                         *pTemp = '\0';
5048         }
5049 }
5050
5051 static bool __MsgIsUTF8String(unsigned char *szSrc, int nChar)
5052 {
5053         MSG_DEBUG("MsgIsUTF8String: --------------- \n");
5054
5055         if (szSrc == NULL) {
5056                 MSG_DEBUG("MsgIsUTF8String: szSrc is NULL !!!! --------------- \n");
5057                 return true;
5058         }
5059
5060         while (nChar > 0 && (*szSrc != '\0')) {
5061                 if (*szSrc < 0x80) {
5062                         szSrc++;
5063                         nChar--;
5064                 } else if ((0xC0 <= *szSrc) && (*szSrc < 0xE0)) {
5065                         if (*(szSrc + 1) >= 0x80) {
5066                                 szSrc += 2;
5067                                 nChar -= 2;
5068                         } else {
5069                                 MSG_DEBUG("MsgIsUTF8String: 1. NOT utf8 range!\n");
5070                                 goto __CATCH;
5071                         }
5072                 } else if (*szSrc >= 0xE0) {
5073                         if (*(szSrc + 1) >= 0x80) {
5074                                 if (*(szSrc + 2) >= 0x80) {
5075                                         szSrc += 3;
5076                                         nChar -= 3;
5077                                 } else {
5078                                         MSG_DEBUG("MsgIsUTF8String: 2. NOT utf8 range!\n");
5079                                         goto __CATCH;
5080                                 }
5081                         } else {
5082                                 MSG_DEBUG("MsgIsUTF8String: 3. NOT utf8 range!\n");
5083                                 goto __CATCH;
5084                         }
5085                 } else {
5086                         MSG_DEBUG("MsgIsUTF8String: 4. NOT utf8 range!\n");
5087                         goto __CATCH;
5088                 }
5089         }
5090
5091         return true;
5092
5093 __CATCH:
5094         return false;
5095 }
5096
5097 static bool __MsgIsPercentSign(char *pSrc)
5098 {
5099         char *pCh = NULL;
5100         bool bRet = false;
5101
5102         pCh = strchr(pSrc , '%');
5103
5104         if (pCh != NULL) {
5105                 bRet = true;
5106         } else {
5107                 bRet = false;
5108         }
5109
5110         return bRet;
5111 }
5112
5113 static MsgMultipart *__MsgAllocMultipart(void)
5114 {
5115         MsgMultipart *pMultipart = NULL;
5116
5117         MSG_DEBUG("MsgAllocMultipart: --------- \n");
5118
5119         pMultipart = (MsgMultipart*)malloc(sizeof(MsgMultipart));
5120         if (pMultipart == NULL) {
5121                 MSG_DEBUG("MsgAllocMultipart: pMultipart malloc Fail \n");
5122                 goto __CATCH;
5123         }
5124
5125         pMultipart->pBody = (MsgBody*)malloc(sizeof(MsgBody));
5126         if (pMultipart->pBody == NULL) {
5127                 MSG_DEBUG("MsgAllocMultipart: pMultipart->pBody malloc Fail \n");
5128                 goto __CATCH;
5129         }
5130
5131         MmsInitMsgType(&pMultipart->type);
5132         MmsInitMsgBody(pMultipart->pBody);
5133
5134         pMultipart->pNext = NULL;
5135
5136         return pMultipart;
5137
5138 __CATCH:
5139
5140         if (pMultipart) {
5141                 if (pMultipart->pBody) {
5142                         free(pMultipart->pBody);
5143                         pMultipart->pBody = NULL;
5144                 }
5145
5146                 free(pMultipart);
5147                 pMultipart = NULL;
5148         }
5149
5150         return NULL;
5151 }
5152
5153 static MsgPresentationFactor __MsgIsPresentationEx(MsgType *multipartType, char* szStart, MimeType typeParam)
5154 {
5155         char szTmpStart[MSG_MSG_ID_LEN + 3] = { 0, };
5156         char szTmpContentID[MSG_MSG_ID_LEN + 3] = { 0, };
5157         char szTmpContentLO[MSG_MSG_ID_LEN + 3] = { 0, };
5158         int strLen = 0;
5159
5160         // remove '<' and '>' in Start Param : contentID ex] <0_1.jpg> or <1233445>
5161         if (szStart && szStart[0]) {
5162                 int startLen = 0;
5163                 startLen = strlen(szStart);
5164                 if (szStart[0] == '<' && szStart[startLen - 1] == '>') {
5165                         strncpy(szTmpStart, &szStart[1], startLen - 2);
5166                 } else {
5167                         strncpy(szTmpStart, szStart, startLen);
5168                 }
5169         }
5170
5171         // remove '<' and '>' in ContentID : contentID ex] <0_1.jpg> or <1233445>
5172         if (multipartType->szContentID[0])      {
5173                 strLen = strlen(multipartType->szContentID);
5174                 if (multipartType->szContentID[0] == '<' && multipartType->szContentID[strLen - 1] == '>') {
5175                         strncpy(szTmpContentID, &(multipartType->szContentID[1]), strLen - 2);
5176                 } else {
5177                         strncpy(szTmpContentID, multipartType->szContentID, strLen);
5178                 }
5179         }
5180
5181         // remove '<' and '>' in ContentLocation : contentID ex] <0_1.jpg> or <1233445>
5182         if (multipartType->szContentLocation[0]) {
5183                 strLen = strlen(multipartType->szContentLocation);
5184                 if (multipartType->szContentLocation[0] == '<' && multipartType->szContentLocation[strLen - 1] == '>') {
5185                         strncpy(szTmpContentLO, &multipartType->szContentLocation[1], strLen - 2);
5186                 } else {
5187                         strncpy(szTmpContentLO, multipartType->szContentLocation, strLen);
5188                 }
5189         }
5190
5191         if ((szTmpContentID[0] == '\0') && (szTmpContentLO[0] == '\0') && (multipartType->type == MIME_UNKNOWN))
5192                 return  MSG_PRESENTATION_NONE;
5193
5194         // exception handling
5195         if (szTmpStart[0] != '\0') {
5196                 // presentation part : 1.compare with contentID 2.compare with content Location 3. compare with type
5197                 if (strcmp(szTmpStart, szTmpContentID) == 0) {
5198                         return MSG_PRESENTATION_ID;
5199                 } else if (strcmp(szTmpStart, szTmpContentLO) == 0) {
5200                         return   MSG_PRESENTATION_LOCATION;
5201                 } else if (multipartType->type == typeParam) {
5202                         return   MSG_PRESENTATION_TYPE_BASE;
5203                 } else {
5204                         return   MSG_PRESENTATION_NONE;
5205                 }
5206         } else {
5207                 if (multipartType->type == typeParam && typeParam != MIME_UNKNOWN) {
5208                         return   MSG_PRESENTATION_TYPE_BASE;
5209                 } else {
5210                         return   MSG_PRESENTATION_NONE;
5211                 }
5212         }
5213 }
5214
5215 static void __MsgConfirmPresentationPart(MsgType *pMsgType, MsgBody *pMsgBody, MsgPresentaionInfo *pPresentationInfo)
5216 {
5217         MSG_BEGIN();
5218         MsgMultipart *pNextPart = NULL;
5219         MsgMultipart *pRemovePart = NULL;
5220
5221         if (__MsgIsMultipartRelated(pMsgType->type)) {
5222                 // assign the multipart to presentation part
5223                 // remove the multipart(pCurPresentation) which is presentation part from the linked list.
5224                 // if there is no presentation part -> assign first multipart to presentation part by force.
5225                 if (pPresentationInfo->pCurPresentation == NULL) {
5226                         pPresentationInfo->pCurPresentation     = pMsgBody->body.pMultipart;
5227                         pPresentationInfo->pPrevPart            = NULL;
5228                         pPresentationInfo->factor                       = MSG_PRESENTATION_NONE;
5229                 }
5230
5231                 if (pPresentationInfo->pCurPresentation != NULL && __MsgIsPresentablePart(pPresentationInfo->pCurPresentation->type.type)) {
5232                         /* Presentable Part is some MARK-UP page, such as SMIL, HTML, WML, XHTML.
5233                          * In this case, COPY the Presentation part and leave other multiparts.
5234                          */
5235                         memcpy(&pMsgBody->presentationType, &pPresentationInfo->pCurPresentation->type, sizeof(MsgType));
5236                         pMsgBody->pPresentationBody = pPresentationInfo->pCurPresentation->pBody;
5237
5238                         // remove pCurPresentation from multipart linked list
5239                         if ((pPresentationInfo->factor == MSG_PRESENTATION_NONE)||(pPresentationInfo->pPrevPart == NULL)) {
5240                                 // first part
5241                                 pMsgBody->body.pMultipart = pPresentationInfo->pCurPresentation->pNext;
5242                                 pMsgType->contentSize -= pPresentationInfo->pCurPresentation->pBody->size;
5243                                 pMsgBody->size -= pPresentationInfo->pCurPresentation->pBody->size;
5244                                 if (pPresentationInfo->pCurPresentation) {
5245 #ifdef __SUPPORT_DRM__
5246                                         MmsReleaseMsgDRMInfo(&pPresentationInfo->pCurPresentation->type.drmInfo);
5247 #endif
5248                                         free(pPresentationInfo->pCurPresentation);
5249                                         pPresentationInfo->pCurPresentation = NULL;
5250                                 }
5251                         } else {
5252                                 // not a first part
5253                                 pPresentationInfo->pPrevPart->pNext = pPresentationInfo->pCurPresentation->pNext;
5254                                 pMsgType->contentSize -= pPresentationInfo->pCurPresentation->pBody->size;
5255                                 pMsgBody->size -= pPresentationInfo->pCurPresentation->pBody->size;
5256                                 if (pPresentationInfo->pCurPresentation) {
5257                                         free(pPresentationInfo->pCurPresentation);
5258                                         pPresentationInfo->pCurPresentation = NULL;
5259                                 }
5260                         }
5261                 } else if (pPresentationInfo->pCurPresentation != NULL && __MsgIsText(pPresentationInfo->pCurPresentation->type.type)) {
5262                         /* NON-Presentable Part is some PLAIN part such as, text/plain, multipart/alternative.
5263                          * In this case, leave the Presentation part as a multipart and remove other multiparts.
5264                          */
5265
5266                         // Backup the multipart link information
5267                         pNextPart = pMsgBody->body.pMultipart;
5268
5269                         // Copy presentation part as a main part
5270                         memcpy(pMsgType, &pPresentationInfo->pCurPresentation->type, sizeof(MsgType));
5271                         memcpy(pMsgBody, pPresentationInfo->pCurPresentation->pBody, sizeof(MsgBody));
5272
5273                         // Remove multipart linked list
5274                         while (pNextPart) {
5275                                 pRemovePart = pNextPart;
5276                                 pNextPart = pNextPart->pNext;
5277
5278                                 if (pRemovePart->pBody) {
5279                                         MmsReleaseMsgBody(pRemovePart->pBody, pRemovePart->type.type);
5280                                         free(pRemovePart->pBody);
5281                                         pRemovePart->pBody = NULL;
5282                                 }
5283
5284                                 free(pRemovePart);
5285                                 pRemovePart = NULL;
5286                         }
5287                 } else {
5288
5289 #ifdef __SUPPORT_DRM__
5290                         MmsReleaseMsgDRMInfo(&pMsgBody->presentationType.drmInfo);
5291 #endif
5292                         MmsInitMsgType(&pMsgBody->presentationType);
5293                         pMsgBody->pPresentationBody = NULL;
5294                 }
5295         }
5296         MSG_END();
5297 }
5298
5299 static bool __MsgIsMultipartRelated(int type)
5300 {
5301         if (type == MIME_MULTIPART_RELATED || type == MIME_APPLICATION_VND_WAP_MULTIPART_RELATED) {
5302                 return true;
5303         } else {
5304                 return false;
5305         }
5306 }
5307
5308 static bool __MsgIsPresentablePart(int type)
5309 {
5310         if (type == MIME_TEXT_HTML || type == MIME_TEXT_VND_WAP_WML || type == MIME_APPLICATION_SMIL) {
5311                 return true;
5312         } else {
5313                 return false;
5314         }
5315 }
5316
5317 #ifdef __SUPPORT_DRM__
5318
5319 bool MsgCopyDrmInfo(MsgType *pPartType)
5320 {
5321         char *pExt = NULL;
5322         char *pTmpBuf = NULL;
5323
5324         //convert application/vnd.oma.drm.content to media type
5325         pPartType->type = pPartType->drmInfo.contentType;
5326
5327         // fix wrong file name presentation on save media screen.
5328         if (pPartType->szContentID[0] == '\0' && pPartType->drmInfo.szContentURI)
5329                 strncpy(pPartType->szContentID, pPartType->drmInfo.szContentURI, MSG_MSG_ID_LEN);
5330
5331         /* set title name (content name) */
5332         if (pPartType->param.szName[0] == '\0') {
5333                 /*      szName is vitual name, real filename is *.dcf or *.dm   */
5334                 if (pPartType->drmInfo.szContentName && pPartType->drmInfo.szContentName[0] != '\0') {
5335                         /* In case of szContentName retrieved from DRM agent is exist. */
5336                         pTmpBuf = pPartType->drmInfo.szContentName;
5337                 } else if (pPartType->szContentLocation[0] != '\0')     {
5338                         /* In case of szContentLocation parsed from MMS header */
5339                         pTmpBuf = strrchr(pPartType->szContentLocation, '/');
5340                         if (pTmpBuf == NULL)
5341                                 pTmpBuf = pPartType->szContentLocation;
5342                 } else {
5343                         /* use another name */
5344                         /* possible NULL pointer assignment*/
5345                         pTmpBuf = strdup("untitled");
5346                 }
5347
5348                 if ((pExt = strrchr(pTmpBuf, '.')) != NULL) {
5349                         int extLen = 0;
5350                         int fileNameLen = 0;
5351                         int tmpLen = 0;
5352
5353                         extLen = strlen(pExt);
5354                         tmpLen = strlen(pTmpBuf);
5355                         fileNameLen = (tmpLen - extLen < MSG_LOCALE_FILENAME_LEN_MAX - extLen)?(tmpLen - extLen):(MSG_LOCALE_FILENAME_LEN_MAX - extLen);
5356                         strncpy(pPartType->param.szName, pTmpBuf, fileNameLen);
5357                         strcpy (pPartType->param.szName + fileNameLen, pExt);
5358                 } else {
5359                         strncpy(pPartType->param.szName, pTmpBuf, MSG_LOCALE_FILENAME_LEN_MAX);
5360                         __MsgMakeFileName(pPartType->type, pPartType->param.szName, MSG_DRM_TYPE_NONE, 0);
5361                 }
5362         }
5363
5364         return true;
5365 }
5366
5367 #endif
5368
5369 static bool __MsgIsText(int type)
5370 {
5371         if (type == MIME_TEXT_PLAIN || type == MIME_TEXT_HTML || type == MIME_TEXT_VND_WAP_WML ||
5372                 type == MIME_TEXT_X_VNOTE || type == MIME_APPLICATION_SMIL || type == MIME_TEXT_X_IMELODY) {
5373                 return true;
5374         } else {
5375                 return false;
5376         }
5377 }
5378
5379
5380
5381 static bool __MsgResolveNestedMultipart(MsgType *pPartType, MsgBody *pPartBody)
5382 {
5383         MSG_BEGIN();
5384         MsgMultipart *pTmpMultipart = NULL;
5385         MsgMultipart *pSelectedPart = NULL;
5386         MsgMultipart *pPrevPart = NULL;
5387         MsgMultipart *pFirstPart = NULL;
5388         MsgMultipart *pLastPart = NULL;
5389         MsgMultipart *pRemoveList = NULL;
5390         MsgMultipart *pNextRemovePart = NULL;
5391
5392         switch (pPartType->type) {
5393         case MIME_APPLICATION_VND_WAP_MULTIPART_ALTERNATIVE:
5394         case MIME_MULTIPART_ALTERNATIVE:
5395
5396                 /* fixme:
5397                  * Policy: multipart/alternative
5398                  * multipart/alternative message has only several parts of media.
5399                  * You should choose one of them and make the alternative part
5400                  * to the selected media part.
5401                  */
5402
5403                 MSG_DEBUG("MsgResolveNestedMultipart : MIME_APPLICATION_VND_WAP_MULTIPART_ALTERNATIVE\n");
5404
5405                 pSelectedPart = pPartBody->body.pMultipart;
5406
5407                 // NULL Pointer check!!
5408                 if (pSelectedPart == NULL) {
5409                         MSG_DEBUG("MsgResolveNestedMultipart : multipart(ALTERNATIVE) does not exist\n");
5410                         break;
5411                 }
5412
5413                 pTmpMultipart = pPartBody->body.pMultipart->pNext;
5414
5415                 while (pTmpMultipart) {
5416                         if (pSelectedPart->type.type <= pTmpMultipart->type.type)
5417                                 pSelectedPart = pTmpMultipart;
5418
5419                         pTmpMultipart = pTmpMultipart->pNext;
5420                 }
5421
5422                 pTmpMultipart = pPartBody->body.pMultipart;
5423                 pPrevPart = NULL;
5424
5425                 while (pTmpMultipart) {
5426                         if (pSelectedPart == pTmpMultipart)
5427                                 break;
5428
5429                         pPrevPart = pTmpMultipart;
5430                         pTmpMultipart = pTmpMultipart->pNext;
5431                 }
5432
5433                 if (pPrevPart == NULL) {
5434                         /* selected part is the first part */
5435                         pRemoveList = pSelectedPart->pNext;
5436                 } else {
5437                         pPrevPart->pNext = pSelectedPart->pNext;
5438                         pRemoveList = pPartBody->body.pMultipart;
5439                         pPartBody->body.pMultipart = pSelectedPart;
5440                 }
5441
5442                 pSelectedPart->pNext = NULL;
5443
5444                 if (pRemoveList) {
5445 #ifdef __SUPPORT_DRM__
5446                         MmsReleaseMsgDRMInfo(&pRemoveList->type.drmInfo);
5447 #endif
5448                         MmsReleaseMsgBody(pRemoveList->pBody, pRemoveList->type.type);
5449
5450                         free(pRemoveList->pBody);
5451                         free(pRemoveList);
5452                 }
5453
5454                 if (__MsgCopyNestedMsgType(pPartType, &(pSelectedPart->type)) == false) {
5455                         MSG_DEBUG("MsgResolveNestedMultipart : MsgPriorityCopyMsgType failed \n");
5456                         goto __CATCH;
5457                 }
5458
5459                 if (pSelectedPart->pBody != NULL)
5460                         memcpy(pPartBody, pSelectedPart->pBody, sizeof(MsgBody));
5461
5462                 if (pSelectedPart != NULL) {
5463 #ifdef __SUPPORT_DRM__
5464                         MmsReleaseMsgDRMInfo(&pSelectedPart->type.drmInfo);
5465 #endif
5466
5467                         if (pSelectedPart->pBody != NULL) {
5468                                 free(pSelectedPart->pBody);
5469                                 pSelectedPart->pBody = NULL;
5470                         }
5471                         free(pSelectedPart);
5472                         pSelectedPart = NULL;
5473                 }
5474
5475                 break;
5476
5477         case MIME_APPLICATION_VND_WAP_MULTIPART_RELATED:
5478         case MIME_MULTIPART_RELATED:
5479
5480                 MSG_DEBUG("MsgResolveNestedMultipart : MIME_APPLICATION_VND_WAP_MULTIPART_RELATED\n");
5481
5482                 pSelectedPart = pPartBody->body.pMultipart;
5483
5484                 while (pSelectedPart) {
5485                         if (__MsgIsMultipartMixed(pSelectedPart->type.type)) {
5486
5487                                 if (pSelectedPart->pBody == NULL) {
5488                                         MSG_DEBUG("MsgResolveNestedMultipart :pSelectedPart->pBody(1) is NULL\n");
5489                                         break;
5490                                 }
5491
5492                                 pFirstPart = pSelectedPart->pBody->body.pMultipart;
5493
5494                                 if (pFirstPart == NULL) {
5495                                         MSG_DEBUG("MsgResolveNestedMultipart : multipart(RELATED) does not exist\n");
5496                                         break;
5497                                 }
5498
5499                                 if (pFirstPart->pNext) {
5500                                         pLastPart = pFirstPart->pNext;
5501                                         while (pLastPart->pNext)
5502                                                 pLastPart = pLastPart->pNext;
5503                                 } else {
5504                                         pLastPart = pFirstPart;
5505                                 }
5506
5507                                 if (pPrevPart == NULL) {
5508                                         /* the first part */
5509                                         pTmpMultipart = pPartBody->body.pMultipart->pNext;
5510                                         pPartBody->body.pMultipart = pFirstPart;
5511                                         pLastPart->pNext = pTmpMultipart;
5512                                 } else {
5513                                         pTmpMultipart = pSelectedPart->pNext;
5514                                         pPrevPart->pNext = pFirstPart;
5515                                         pLastPart->pNext = pTmpMultipart;
5516                                 }
5517
5518                                 if (pSelectedPart) {
5519 #ifdef __SUPPORT_DRM__
5520                                         MmsReleaseMsgDRMInfo(&pSelectedPart->type.drmInfo);
5521 #endif
5522                                         free(pSelectedPart->pBody);
5523                                         free(pSelectedPart);
5524                                 }
5525                                 pSelectedPart = pTmpMultipart;
5526                         } else if (__MsgIsMultipartRelated(pSelectedPart->type.type) && pPrevPart != NULL) {
5527                                 pPrevPart->pNext = pTmpMultipart = pSelectedPart->pNext;
5528                                 MmsReleaseMsgBody(pSelectedPart->pBody, pSelectedPart->type.type);
5529
5530                                 free(pSelectedPart->pBody);
5531                                 free(pSelectedPart);
5532                                 pSelectedPart = pTmpMultipart;
5533                         } else {
5534                                 pPrevPart = pSelectedPart;
5535                                 pSelectedPart = pSelectedPart->pNext;
5536                         }
5537                 }
5538
5539                 break;
5540
5541
5542         case MIME_APPLICATION_VND_WAP_MULTIPART_MIXED:
5543         case MIME_MULTIPART_MIXED:
5544
5545                 MSG_DEBUG("MsgResolveNestedMultipart : MIME_APPLICATION_VND_WAP_MULTIPART_MIXED\n");
5546
5547                 pPrevPart = NULL;
5548                 pSelectedPart = pPartBody->body.pMultipart;
5549
5550                 while (pSelectedPart) {
5551                         if (MsgIsMultipart(pSelectedPart->type.type)) {
5552                                 if (pSelectedPart->pBody == NULL) {
5553                                         MSG_DEBUG("MsgResolveNestedMultipart :pSelectedPart->pBody(2) is NULL\n");
5554                                         break;
5555                                 }
5556
5557                                 pFirstPart = pSelectedPart->pBody->body.pMultipart;
5558
5559                                 // NULL Pointer check!!
5560                                 if (pFirstPart == NULL) {
5561                                         MSG_DEBUG("MsgResolveNestedMultipart : multipart does not exist\n");
5562                                         break;
5563                                 }
5564
5565                                 if (pFirstPart->pNext) {
5566                                         pLastPart = pFirstPart->pNext;
5567                                         while (pLastPart->pNext)
5568                                                 pLastPart = pLastPart->pNext;
5569                                 } else {
5570                                         pLastPart = pFirstPart;
5571                                 }
5572
5573                                 if (pPrevPart == NULL) {
5574                                         /* the first part */
5575                                         pTmpMultipart = pPartBody->body.pMultipart->pNext;
5576                                         pPartBody->body.pMultipart = pFirstPart;
5577                                         pLastPart->pNext = pTmpMultipart;
5578                                 } else {
5579                                         pTmpMultipart = pSelectedPart->pNext;
5580                                         pPrevPart->pNext = pFirstPart;
5581                                         pLastPart->pNext = pTmpMultipart;
5582                                 }
5583
5584                                 if (pSelectedPart->pBody->pPresentationBody)
5585                                         pPartBody->pPresentationBody = pSelectedPart->pBody->pPresentationBody;
5586
5587                                 memcpy(&pPartBody->presentationType,
5588                                                   &pSelectedPart->pBody->presentationType, sizeof(MsgType));
5589
5590                                 pPartType->type = pSelectedPart->type.type;
5591
5592 #ifdef __SUPPORT_DRM__
5593                                 MmsReleaseMsgDRMInfo(&pSelectedPart->type.drmInfo);
5594 #endif
5595                                 free(pSelectedPart->pBody);
5596                                 free(pSelectedPart);
5597
5598                                 pSelectedPart = pTmpMultipart;
5599                         } else {
5600                                 pPrevPart = pSelectedPart;
5601                                 pSelectedPart = pSelectedPart->pNext;
5602                         }
5603                 }
5604
5605                 break;
5606
5607         case MIME_MULTIPART_REPORT:
5608
5609                 MSG_DEBUG("MsgResolveNestedMultipart : MIME_MULTIPART_REPORT \n");
5610
5611                 pTmpMultipart = pPartBody->body.pMultipart;
5612                 pPrevPart = NULL;
5613
5614                 if (pTmpMultipart == NULL) {
5615                         MSG_DEBUG("MsgResolveNestedMultipart : pTmpMultipart == NULL \n");
5616                         return false;
5617                 }
5618
5619                 while (pTmpMultipart) {
5620                         if (pTmpMultipart->type.type == MIME_TEXT_PLAIN) {
5621                                 pSelectedPart = pTmpMultipart;
5622                                 break;
5623                         }
5624
5625                         pPrevPart = pTmpMultipart;
5626                         pTmpMultipart = pTmpMultipart->pNext;
5627                 }
5628
5629                 if (pSelectedPart == NULL) {
5630                         MSG_DEBUG("MsgResolveNestedMultipart : MIME_MULTIPART_REPORT [no selected part]\n");
5631
5632                         pRemoveList = pPartBody->body.pMultipart->pNext;
5633                         if (pPartBody->body.pMultipart != NULL) {
5634                                 pSelectedPart = pPartBody->body.pMultipart;
5635                                 pSelectedPart->pNext = NULL;
5636                         }
5637                 } else {
5638                         if (pPrevPart == NULL) {
5639                                 // first part is selected
5640                                 pRemoveList = pPartBody->body.pMultipart->pNext;
5641                         } else {
5642                                 pRemoveList = pPartBody->body.pMultipart->pNext;
5643                                 pPrevPart->pNext = pSelectedPart->pNext;
5644                         }
5645
5646                         pSelectedPart->pNext = NULL;
5647                         pPartBody->body.pMultipart = pSelectedPart;
5648                 }
5649
5650                 pTmpMultipart = pRemoveList;
5651
5652                 while (pTmpMultipart) {
5653 #ifdef __SUPPORT_DRM__
5654                         MmsReleaseMsgDRMInfo(&pTmpMultipart->type.drmInfo);
5655 #endif
5656                         MmsReleaseMsgBody(pTmpMultipart->pBody, pTmpMultipart->type.type);
5657                         pNextRemovePart = pTmpMultipart->pNext;
5658
5659                         free(pTmpMultipart->pBody);
5660                         free(pTmpMultipart);
5661                         pTmpMultipart = pNextRemovePart;
5662                 }
5663
5664                 if (__MsgCopyNestedMsgType(pPartType, &(pSelectedPart->type)) == false) {
5665                         MSG_DEBUG("MsgResolveNestedMultipart : MsgPriorityCopyMsgType failed \n");
5666                         goto __CATCH;
5667                 }
5668
5669                 if (pSelectedPart != NULL) {
5670
5671                         if (pSelectedPart->pBody != NULL)
5672                                 memcpy(pPartBody, pSelectedPart->pBody, sizeof(MsgBody));
5673
5674 #ifdef __SUPPORT_DRM__
5675                         MmsReleaseMsgDRMInfo(&pSelectedPart->type.drmInfo);
5676 #endif
5677                         if (pSelectedPart->pBody != NULL) {
5678                                 free(pSelectedPart->pBody);
5679                                 pSelectedPart->pBody = NULL;
5680                         }
5681                         free(pSelectedPart);
5682                         pSelectedPart = NULL;
5683                 }
5684
5685                 break;
5686
5687         default:
5688                 break;
5689         }
5690         MSG_END();
5691
5692         return true;
5693
5694 __CATCH:
5695         return false;
5696
5697 }
5698
5699 char *MsgResolveContentURI(char *szSrc)
5700 {
5701         char *szTemp = NULL;
5702         char *szReturn = NULL;
5703         int length = 0;
5704
5705         if (szSrc == NULL) {
5706                 goto __CATCH;
5707         }
5708
5709         if (szSrc[0] == '\0')
5710                 goto __CATCH;
5711
5712
5713         if (!strncasecmp(szSrc, "cid:", 4)) {
5714                 length = strlen(szSrc) - 3;
5715                 szSrc += 4;
5716         } else {
5717                 length = strlen(szSrc) + 1;
5718         }
5719
5720         szTemp = (char *)malloc(length);
5721         if (szTemp == NULL) {
5722                 MSG_DEBUG("MsgResolveContentURI: memory full\n");
5723                 goto __CATCH;
5724         }
5725
5726         memset(szTemp, 0, length);
5727         strcpy(szTemp, szSrc);
5728
5729         szReturn = MsgChangeHexString(szTemp);
5730
5731         if (szTemp) {
5732                 free(szTemp);
5733                 szTemp = NULL;
5734         }
5735
5736         return szReturn;
5737
5738 __CATCH:
5739
5740         return NULL;
5741 }
5742
5743 char *MsgRemoveQuoteFromFilename(char *pSrc)
5744 {
5745         int cLen = 0;   // length of pBuff
5746         char *pBuff = NULL;
5747
5748         if (pSrc == NULL) {
5749                 MSG_DEBUG("MsgRemoveQuoteFromFilename: pSrc is Null\n");
5750                 return NULL;
5751         }
5752
5753         cLen = strlen(pSrc);
5754
5755         pBuff = (char *)malloc(cLen + 1);
5756
5757         if (pBuff == NULL) {
5758                 MSG_DEBUG("MsgRemoveQuoteFromFilename: pBuff mem alloc fail!\n");
5759                 return NULL;
5760         }
5761         memset(pBuff, 0 , sizeof(char)*(cLen + 1));
5762
5763         // remove front quote
5764         if (pSrc[0] == MSG_CH_QUOT) {
5765                 cLen--;
5766                 strncpy(pBuff, &pSrc[1], cLen);
5767                 pBuff[cLen] = '\0';
5768         }
5769
5770         if (pSrc[0] == MSG_CH_LF) {
5771                 cLen--;
5772                 strncpy(pBuff, &pSrc[1], cLen);
5773         } else {
5774                 strcpy(pBuff, pSrc);
5775         }
5776
5777         // remove last qoute
5778         if (pBuff[cLen-1] == MSG_CH_QUOT) {
5779                 pBuff[cLen-1] = '\0';
5780         }
5781
5782         return pBuff;
5783 }
5784
5785 bool MsgIsMultipart(int type)
5786 {
5787         if (type == MIME_MULTIPART_RELATED || type == MIME_APPLICATION_VND_WAP_MULTIPART_MIXED ||
5788                 type == MIME_APPLICATION_VND_WAP_MULTIPART_RELATED || type == MIME_APPLICATION_VND_WAP_MULTIPART_ASTERIC ||
5789                 type == MIME_MULTIPART_MIXED || type == MIME_MULTIPART_REPORT) {
5790                 return true;
5791         } else {
5792                 return false;
5793         }
5794 }
5795
5796
5797 static bool __MsgIsHexChar(char *pSrc)
5798 {
5799         int cIndex = 0;
5800         int cLen = 0;
5801         bool bRet = false;
5802
5803         cLen = strlen(pSrc);
5804
5805         for (cIndex = 0; cIndex < cLen ; cIndex++) {
5806                 if ((pSrc[cIndex] >= '0' && pSrc[cIndex] <= '9') || (pSrc[cIndex] >= 'A'&& pSrc[cIndex] <= 'F') ||
5807                         (pSrc[cIndex] >= 'a' && pSrc[cIndex] <= 'f')) {
5808                         bRet = true;
5809                 } else {
5810                         return false;
5811                 }
5812         }
5813
5814         return bRet;
5815 }
5816
5817 static char __MsgConvertHexValue(char *pSrc)
5818 {
5819         int ch = 0;
5820         int cIndex = 0;
5821         int cLen = 0;
5822         char ResultChar;
5823         unsigned char uCh[2] = {0,};
5824
5825         cLen = strlen(pSrc);
5826
5827         for (cIndex = 0; cIndex < cLen ; cIndex += 2) {
5828                 uCh[0] = __MsgConvertCharToInt(pSrc[cIndex]);
5829                 uCh[1] = __MsgConvertCharToInt(pSrc[cIndex+1]);
5830                 ch = (int)uCh[0]<<4|uCh[1];
5831         }
5832
5833         ResultChar = (char)ch;
5834
5835         return ResultChar;
5836 }
5837
5838 static int __MsgConvertCharToInt(char ch)
5839 {
5840         if (ch>='0' && ch<='9') {
5841                 return ch - '0';
5842         } else if (ch>='a'&& ch <='f') {
5843                 return ch -'a'+10;
5844         } else if (ch>='A'&& ch <='F') {
5845                 return ch -'A'+10;
5846         } else {
5847                 return 0;
5848         }
5849 }
5850
5851 static bool __MsgCopyNestedMsgType(MsgType *pMsgType1, MsgType *pMsgType2)
5852 {
5853         if(!pMsgType1 || !pMsgType2)
5854                 return false;
5855
5856         if (pMsgType1->section == INVALID_HOBJ)
5857                 pMsgType1->section = pMsgType2->section;
5858
5859 #ifdef __SUPPORT_DRM__
5860         int             length = 0;
5861
5862         if (pMsgType1->drmInfo.drmType == MSG_DRM_TYPE_NONE)
5863                 pMsgType1->drmInfo.drmType = pMsgType2->drmInfo.drmType;
5864
5865
5866         if (pMsgType1->szContentID[0] == '\0') {
5867                 strcpy(pMsgType1->szContentID, pMsgType2->szContentID);
5868
5869                 if (pMsgType2->szContentID[0]) {
5870                         length = MsgStrlen(pMsgType2->szContentID);
5871                         if (pMsgType2->szContentID[0] == '<' && pMsgType2->szContentID[length - 1] == '>') {
5872                                 pMsgType1->drmInfo.szContentURI = MsgStrNCopy(pMsgType2->szContentID + 1, length - 2);
5873                         } else {
5874                                 pMsgType1->drmInfo.szContentURI = MsgStrCopy(pMsgType2->szContentID);
5875                         }
5876                 }
5877         } else {
5878                 length = MsgStrlen(pMsgType1->szContentID);
5879                 if (pMsgType1->szContentID[0] == '<' && pMsgType1->szContentID[length - 1] == '>') {
5880                         pMsgType1->drmInfo.szContentURI = MsgStrNCopy(pMsgType1->szContentID + 1, length - 2);
5881                 } else {
5882                         pMsgType1->drmInfo.szContentURI = MsgStrCopy(pMsgType1->szContentID);
5883                 }
5884         }
5885 #endif
5886
5887         if (pMsgType1->szContentLocation[0] == '\0')
5888                 strcpy(pMsgType1->szContentLocation, pMsgType2->szContentLocation);
5889
5890         /* Copy informations - we shoud open the pMsgType2's orgFile
5891          * concerning its offset and size.
5892          */
5893         if (pMsgType2->szOrgFilePath[0] != '\0')
5894                 strcpy(pMsgType1->szOrgFilePath, pMsgType2->szOrgFilePath);
5895
5896         if (pMsgType2->disposition != INVALID_HOBJ)
5897                 pMsgType1->disposition = pMsgType2->disposition;
5898
5899         if ((pMsgType1->type != MIME_APPLICATION_VND_OMA_DRM_MESSAGE && pMsgType1->type != MIME_APPLICATION_VND_OMA_DRM_CONTENT) &&
5900                  pMsgType2->encoding != INVALID_HOBJ)
5901                 pMsgType1->encoding = pMsgType2->encoding;
5902
5903         pMsgType1->contentSize = pMsgType2->contentSize;
5904         pMsgType1->offset = pMsgType2->offset;
5905         pMsgType1->size = pMsgType2->size;
5906         pMsgType1->type = pMsgType2->type;
5907
5908         __MsgCopyNestedMsgParam(&(pMsgType1->param), &(pMsgType2->param));
5909
5910         if (pMsgType1->param.szName[0]) {
5911 #ifdef __SUPPORT_DRM__
5912                 pMsgType1->drmInfo.szContentName = MsgStrCopy(pMsgType2->param.szName);
5913 #endif
5914         }
5915
5916         return true;
5917 }
5918
5919 static bool __MsgCopyNestedMsgParam(MsgContentParam *pParam1, MsgContentParam *pParam2)
5920 {
5921         if (pParam1->charset == MSG_CHARSET_UNKNOWN)
5922                 pParam1->charset = pParam2->charset;
5923
5924         if (pParam1->type == MIME_UNKNOWN)
5925                 pParam1->type = pParam2->type;
5926
5927         /* Don't copy pParam2->pPresentation */
5928
5929         /* For alternative: copy the boundary string */
5930         if (pParam2->szBoundary[0] !='\0')
5931                 strcpy(pParam1->szBoundary, pParam2->szBoundary);
5932
5933         if (pParam1->szFileName[0] =='\0')
5934                 strcpy(pParam1->szFileName, pParam2->szFileName);
5935
5936         if (pParam1->szName[0] =='\0')
5937                 strcpy(pParam1->szName, pParam2->szName);
5938
5939         if (pParam1->szStart[0] =='\0')
5940                 strcpy(pParam1->szStart, pParam2->szStart);
5941
5942         if (pParam1->szStartInfo[0] =='\0')
5943                 strcpy(pParam1->szStartInfo, pParam2->szStartInfo);
5944
5945         return true;
5946 }
5947
5948 static bool __MsgIsMultipartMixed(int type)
5949 {
5950         if (type == MIME_APPLICATION_VND_WAP_MULTIPART_MIXED || type == MIME_MULTIPART_MIXED) {
5951                 return true;
5952         } else {
5953                 return false;
5954         }
5955 }
5956
5957 bool MmsGetMsgAttrib(MmsMsgID msgID, MmsAttrib* pAttrib)
5958 {
5959         MmsMsg *pMsg = NULL;
5960
5961         memset(pAttrib, 0, sizeof(MmsAttrib));
5962         MmsPluginStorage::instance()->getMmsMessage(&pMsg);
5963         memcpy(pAttrib, &(pMsg->mmsAttrib), sizeof(MmsAttrib));
5964
5965         MSG_DEBUG("MmsGetMsgAttrib: msgID = %lu ---------------------\n", msgID);
5966
5967         if ('\0' != pMsg->szTrID[0])
5968                 MSG_DEBUG("szTrID = %s \n", pMsg->szTrID);
5969
5970         MSG_END();
5971         return true;
5972 }
5973
5974 static bool __MsgIsInvalidFileNameChar(char ch)
5975 {
5976         if ((ch == 0x5C /* \ */) ||
5977                 (ch == 0x2F /* / */) ||
5978                 (ch == 0x3A /* : */) ||
5979                 (ch == 0x2A /* * */) ||
5980                 (ch == 0x3F /* ? */) ||
5981                 (ch == 0x22 /* " */) ||
5982                 (ch == 0x3C /* < */) ||
5983                 (ch == 0x3E /* > */) ||
5984                 (ch == 0x7C /* | */))
5985                 return true;
5986
5987         return false;
5988 }
5989
5990 bool MmsDataUpdateLastStatus(MmsMsg *pMsg)
5991 {
5992         MmsMsgMultiStatus*      pStatus = NULL;
5993
5994         pStatus = pMsg->mmsAttrib.pMultiStatus;
5995
5996         while (pStatus != NULL) {
5997                 pStatus->bDeliveyrReportIsLast = false;
5998                 pStatus->bReadReplyIsLast = false;
5999                 pStatus = pStatus->pNext;
6000         }
6001
6002         return true;
6003 }
6004
6005
6006 bool MmsAddrUtilCompareAddr(char *pszAddr1, char *pszAddr2)
6007 {
6008         int len1;
6009         int len2;
6010         char *p;
6011
6012         MmsAddrUtilRemovePlmnString(pszAddr1);
6013         MmsAddrUtilRemovePlmnString(pszAddr2);
6014
6015         MSG_DEBUG("##### pszAddr1 = %s #####", pszAddr1);
6016         MSG_DEBUG("##### pszAddr2 = %s #####", pszAddr2);
6017         if (!strcmp(pszAddr1, pszAddr2))
6018                 return true;
6019
6020         len1 = strlen(pszAddr1);
6021         len2 = strlen(pszAddr2);
6022
6023         if (len1 > len2) {
6024                 p = strstr(pszAddr1, pszAddr2);
6025         } else {
6026                 p = strstr(pszAddr2, pszAddr1);
6027         }
6028
6029         if (p)
6030                 return true;
6031
6032         return false;
6033 }
6034
6035 static int __MsgGetLatin2UTFCodeSize(unsigned char *szSrc, int nChar)
6036 {
6037         int nCount = 0;
6038
6039         MSG_DEBUG("MsgGetLatin2UTFCodeSize: --------------- \n");
6040
6041         if ((szSrc == NULL) || (nChar <= 0)) {
6042                 MSG_DEBUG("MsgGetLatin2UTFCodeSize: szSrc is NULL !!!! --------------- \n");
6043                 return 0;
6044         }
6045
6046         while ((nChar > 0) && (*szSrc != '\0')) {
6047                 if (0x01 <= *szSrc && *szSrc <= 0x7F) {
6048                         nCount += 1;
6049                         szSrc++;
6050                         nChar--;
6051                 } else {
6052                         nCount += 2;
6053                         szSrc++;
6054                         nChar--;
6055                 }
6056         }
6057
6058         return nCount;
6059 }
6060
6061 static int __MsgLatin5code2UTF(unsigned char *des, int outBufSize, unsigned char *szSrc, int nChar)
6062 {
6063         unsigned char *org;
6064         unsigned char t1;
6065         unsigned char t2;
6066         unsigned short temp = 0;
6067
6068         org = des;
6069         outBufSize--;   //Null Character
6070
6071         while ((nChar > 0) && (*szSrc != '\0')) {
6072
6073                 if (*szSrc >= 0x01 && *szSrc <= 0x7F) { //basic common
6074                         temp = (unsigned short)(*szSrc);
6075
6076                         outBufSize --;
6077                         if (outBufSize < 0)
6078                                 goto __RETURN;
6079
6080                         *des = (unsigned char) ((*szSrc) & 0x007F);
6081
6082                         des++;
6083                         szSrc++;
6084                         nChar--;
6085                 } else if ((*szSrc == 0x00) || (*szSrc >= 0x80 && *szSrc <= 0x9F) ||
6086                                         (*szSrc >= 0xA0 && *szSrc <= 0xCF) || (*szSrc >= 0xD1 && *szSrc <= 0xDC) ||
6087                                         (*szSrc >= 0xDF && *szSrc <= 0xEF) || (*szSrc >= 0xF1 && *szSrc <= 0xFC) ||
6088                                         (*szSrc == 0xFF)) {//uni 0x00A0 ~ 0x00CF
6089
6090                         temp = (unsigned short)(*szSrc);
6091
6092                         outBufSize -= 2;
6093                         if (outBufSize < 0)
6094                                 goto __RETURN;
6095
6096                         t2 = (unsigned char) (temp & 0x003F);                           //      right most 6 bit
6097                         t1 = (unsigned char) ((temp & 0x07C0) >> 6);            //      right most 5 bit
6098
6099                         *des = 0xC0 | (t1 & 0x1F);
6100                         *(des+1) = 0x80 | (t2 & 0x3F);
6101
6102                         des += 2;
6103                         szSrc += 1;
6104                         nChar -= 1;
6105                 } else if (*szSrc == 0xD0) {//empty section OR vendor specific codes.
6106
6107                         temp = 0x011E;
6108
6109                         outBufSize -= 2;
6110                         if (outBufSize < 0)
6111                                 goto __RETURN;
6112
6113                         t2 = (unsigned char) (temp & 0x003F);                           //      right most 6 bit
6114                         t1 = (unsigned char) ((temp & 0x07C0) >> 6);            //      right most 5 bit
6115
6116                         *des = 0xC0 | (t1 & 0x1F);
6117                         *(des+1) = 0x80 | (t2 & 0x3F);
6118
6119                         des += 2;
6120                         szSrc += 1;
6121                         nChar -= 1;
6122                 } else if (*szSrc == 0xDD) {
6123                         temp = 0x0130;
6124
6125                         outBufSize -= 2;
6126                         if (outBufSize < 0)
6127                                 goto __RETURN;
6128
6129                         t2 = (unsigned char) (temp & 0x003F);                           //      right most 6 bit
6130                         t1 = (unsigned char) ((temp & 0x07C0) >> 6);            //      right most 5 bit
6131
6132                         *des = 0xC0 | (t1 & 0x1F);
6133                         *(des+1) = 0x80 | (t2 & 0x3F);
6134
6135                         des += 2;
6136                         szSrc += 1;
6137                         nChar -= 1;
6138                 } else if (*szSrc == 0xDE) {
6139                         temp = 0x015E;
6140
6141                         outBufSize -= 2;
6142                         if (outBufSize < 0)
6143                                 goto __RETURN;
6144
6145                         t2 = (unsigned char) (temp & 0x003F);                           //      right most 6 bit
6146                         t1 = (unsigned char) ((temp & 0x07C0) >> 6);            //      right most 5 bit
6147
6148                         *des = 0xC0 | (t1 & 0x1F);
6149                         *(des+1) = 0x80 | (t2 & 0x3F);
6150
6151                         des += 2;
6152                         szSrc += 1;
6153                         nChar -= 1;
6154                 } else if (*szSrc == 0xF0) {
6155                         temp = 0x011F;
6156                                 outBufSize -= 2;
6157                         if (outBufSize < 0)
6158                                 goto __RETURN;
6159
6160                         t2 = (unsigned char) (temp & 0x003F);                           //      right most 6 bit
6161                         t1 = (unsigned char) ((temp & 0x07C0) >> 6);            //      right most 5 bit
6162
6163                         *des = 0xC0 | (t1 & 0x1F);
6164                         *(des+1) = 0x80 | (t2 & 0x3F);
6165
6166                         des += 2;
6167                         szSrc += 1;
6168                         nChar -= 1;
6169                 } else if (*szSrc == 0xFD) {
6170                         temp = 0x0131;
6171
6172                         outBufSize -= 2;
6173
6174                         if (outBufSize < 0)
6175                                 goto __RETURN;
6176
6177                         t2 = (unsigned char) (temp & 0x003F);                           //      right most 6 bit
6178                         t1 = (unsigned char) ((temp & 0x07C0) >> 6);            //      right most 5 bit
6179
6180                         *des = 0xC0 | (t1 & 0x1F);
6181                         *(des+1) = 0x80 | (t2 & 0x3F);
6182
6183                         des += 2;
6184                         szSrc += 1;
6185                         nChar -= 1;
6186                 } else if (*szSrc == 0xFE) {
6187                         temp = 0x015F;
6188
6189                         outBufSize -= 2;
6190                         if (outBufSize < 0)
6191                                 goto __RETURN;
6192
6193                         t2 = (unsigned char) (temp & 0x003F);                           //      right most 6 bit
6194                         t1 = (unsigned char) ((temp & 0x07C0) >> 6);            //      right most 5 bit
6195
6196                         *des = 0xC0 | (t1 & 0x1F);
6197                         *(des+1) = 0x80 | (t2 & 0x3F);
6198
6199                         des += 2;
6200                         szSrc += 1;
6201                         nChar -= 1;
6202                 } else {
6203                         return -1;
6204                 }
6205         }
6206 __RETURN:
6207         *des = 0;
6208         return(des-org);
6209 }
6210
6211 static int __MsgGetLatin52UTFCodeSize(unsigned char *szSrc, int nChar)
6212 {
6213         int nCount = 0;
6214
6215         MSG_DEBUG("MsgGetLatin52UTFCodeSize: --------------- \n");
6216
6217         if ((szSrc == NULL) || (nChar <= 0))
6218                 return 0;
6219
6220         while ((nChar > 0) && (*szSrc != '\0')) {
6221                 if (*szSrc >= 0x01 && *szSrc <= 0x7F) {
6222                         nCount += 1;
6223                         szSrc++;
6224                         nChar--;
6225                 } else if (*szSrc == 0x00 || (*szSrc >= 0x80 && *szSrc <= 0x9F) ||
6226                                         (*szSrc >= 0xA0 && *szSrc <= 0xCF) || (*szSrc >= 0xD1 && *szSrc <= 0xDC) |
6227                                         (*szSrc >= 0xDF && *szSrc <= 0xEF) || (*szSrc >= 0xF1 && *szSrc <= 0xFC) ||
6228                                         *szSrc == 0xD0 || *szSrc == 0xDD || *szSrc == 0xDE || *szSrc == 0xF0 ||
6229                                         *szSrc == 0xFD || *szSrc == 0xFE        || *szSrc == 0xFF) { //uni 0x00A0 ~ 0x00CF
6230                         nCount += 2;
6231                         szSrc++;
6232                         nChar--;
6233                 } else {
6234                         return -1;
6235                 }
6236         }
6237         return nCount;
6238 }
6239
6240 static int __MsgLatin2UTF(unsigned char *des, int outBufSize, unsigned char *szSrc, int nChar)
6241 {
6242         unsigned char*  org;
6243         unsigned char   t1, t2;
6244
6245         MSG_DEBUG("MsgLatin2UTF: --------------- \n");
6246
6247         org = des;
6248         outBufSize--;                   // NULL character
6249
6250         while ((nChar > 0) && (*szSrc != '\0')) {
6251                 if (0x01 <= *szSrc && *szSrc <= 0x7F) {
6252                         /* check outbuffer's room for this UTF8 character */
6253
6254                         outBufSize --;
6255                         if (outBufSize < 0)
6256                                 goto __RETURN;
6257
6258                         *des = (unsigned char) (*szSrc & 0x007F);
6259
6260                         des++;
6261                         szSrc++;
6262                         nChar--;
6263                 } else {
6264                         /* check outbuffer's room for this UTF8 character */
6265
6266                         outBufSize -= 2;
6267                         if (outBufSize < 0)
6268                                 goto __RETURN;
6269
6270                         t2 = (unsigned char) (*szSrc & 0x003F);                         //      right most 6 bit
6271                         t1 = (unsigned char) ((*szSrc & 0xC0) >> 6);            //      right most 2 bit
6272
6273                         *des = 0xC0 | (t1 & 0x1F);
6274                         *(des + 1) = 0x80 | (t2 & 0x3F);
6275
6276                         des += 2;
6277                         szSrc += 1;
6278                         nChar -= 1;
6279                 }
6280         }
6281
6282 __RETURN:
6283
6284         *des = 0;
6285         return (des - org);
6286 }
6287
6288
6289 static int __MsgLatin7code2UTF(unsigned char *des, int outBufSize, unsigned char *szSrc, int nChar)
6290 {
6291         unsigned char *org;
6292         unsigned char t1;
6293         unsigned char t2;
6294         unsigned char t3;
6295         unsigned short temp = 0;
6296
6297         MSG_DEBUG("MsgUnicode2UTF: --------------- \n");
6298
6299         org = des;
6300         outBufSize--;   //Null Character
6301
6302         while ((nChar > 0) && (*szSrc != '\0')) {
6303                 if (*szSrc >= 0x01 && *szSrc <= 0x7F) {
6304                         temp = (unsigned short)(*szSrc);
6305
6306                         outBufSize --;
6307                         if (outBufSize < 0)
6308                                 goto __RETURN;
6309
6310                         *des = (unsigned char) (temp & 0x007F);
6311
6312                         des++;
6313                         szSrc++;
6314                         nChar--;
6315
6316                 } else if ((*szSrc == 0x00) || (*szSrc >= 0x80 && *szSrc <= 0x9F) ||
6317                                         (*szSrc >= 0xA3 && *szSrc <= 0xAD) || (*szSrc == 0xBB)) { // consider 0xA4, 0xA5
6318
6319                         temp = (unsigned short)(*szSrc);
6320
6321                         outBufSize -= 2;
6322                         if (outBufSize < 0)
6323                                 goto __RETURN;
6324
6325                         t2 = (unsigned char) (temp & 0x003F);                           //      right most 6 bit
6326                         t1 = (unsigned char) ((temp & 0xC0) >> 6);              //      right most 2 bit
6327
6328                         *des = 0xC0 | (t1 & 0x1F);
6329                         *(des + 1) = 0x80 | (t2 & 0x3F);
6330
6331                         des += 2;
6332                         szSrc += 1;
6333                         nChar -= 1;
6334                 } else if (*szSrc == 0xA0) {
6335                         temp = 0x0020;
6336                         //*des = temp to utf-8
6337                         outBufSize--;
6338                         if (outBufSize < 0)
6339                                 goto __RETURN;
6340
6341                         *des = (unsigned char) (temp & 0x007F);
6342
6343                         des++;
6344                         szSrc++;
6345                         nChar--;
6346
6347                 } else if (*szSrc == 0xA1) {
6348                         temp = 0x2018;
6349
6350                         outBufSize -= 3;
6351                         if (outBufSize < 0)
6352                                 goto __RETURN;
6353
6354                         t3 = (unsigned char) (temp & 0x003F);                                   //      right most 6 bit
6355                         t2 = (unsigned char) ((temp & 0x0FC0) >> 6);                    //      right most 6 bit
6356                         t1 = (unsigned char) ((temp & 0xF000) >> 12);                   //      right most 4 bit
6357
6358                         *des = 0xE0 | (t1 & 0x0F);
6359                         *(des+1) = 0x80 | (t2 & 0x3F);
6360                         *(des+2) = 0x80 | (t3 & 0x3F);
6361
6362                         des += 3;
6363                         szSrc += 1;
6364                         nChar -= 1;
6365
6366                 } else if (*szSrc == 0xA2) {
6367                         temp = 0x2019;
6368
6369                         outBufSize -= 3;
6370                         if (outBufSize < 0)
6371                                 goto __RETURN;
6372
6373                         t3 = (unsigned char) (temp & 0x003F);                                   //      right most 6 bit
6374                         t2 = (unsigned char) ((temp & 0x0FC0) >> 6);                    //      right most 6 bit
6375                         t1 = (unsigned char) ((temp & 0xF000) >> 12);                   //      right most 4 bit
6376
6377                         *des = 0xE0 | (t1 & 0x0F);
6378                         *(des+1) = 0x80 | (t2 & 0x3F);
6379                         *(des+2) = 0x80 | (t3 & 0x3F);
6380
6381                         des += 3;
6382                         szSrc += 1;
6383                         nChar -= 1;
6384
6385                 } else if (*szSrc == 0xAF) {
6386                         temp = 0x2015;
6387
6388                         outBufSize -= 3;
6389                         if (outBufSize < 0)
6390                                 goto __RETURN;
6391
6392                         t3 = (unsigned char) (temp & 0x003F);                                   //      right most 6 bit
6393                         t2 = (unsigned char) ((temp & 0x0FC0) >> 6);                    //      right most 6 bit
6394                         t1 = (unsigned char) ((temp & 0xF000) >> 12);                   //      right most 4 bit
6395
6396                         *des = 0xE0 | (t1 & 0x0F);
6397                         *(des+1) = 0x80 | (t2 & 0x3F);
6398                         *(des+2) = 0x80 | (t3 & 0x3F);
6399
6400                         des += 3;
6401                         szSrc += 1;
6402                         nChar -= 1;
6403
6404                 } else if (0xB0 <= *szSrc && *szSrc <= 0xB4) { //0x00B0 ~ 0x00B4
6405
6406                         temp = (unsigned short)(*szSrc);
6407
6408                         outBufSize -= 2;
6409                         if (outBufSize < 0)
6410                                 goto __RETURN;
6411
6412                         t2 = (unsigned char) (temp & 0x003F);                           //      right most 6 bit
6413                         t1 = (unsigned char) ((temp & 0x07C0) >> 6);            //      right most 5 bit
6414
6415                         *des = 0xC0 | (t1 & 0x1F);
6416                         *(des+1) = 0x80 | (t2 & 0x3F);
6417
6418                         des += 2;
6419                         szSrc += 1;
6420                         nChar -= 1;
6421
6422                 } else if ((0xB5 <= *szSrc &&  *szSrc <= 0xBA) ||
6423                                 (0xBC <= *szSrc && *szSrc <= 0xD1) ||
6424                                 (0xD3 <= *szSrc && *szSrc <= 0xFE)) {
6425                         temp= (unsigned short)(*szSrc + 0x02D0);
6426
6427                         outBufSize -= 2;
6428                         if (outBufSize < 0)
6429                                 goto __RETURN;
6430
6431                         t2 = (unsigned char) (temp & 0x003F);                           //      right most 6 bit
6432                         t1 = (unsigned char) ((temp & 0x07C0) >> 6);            //      right most 5 bit
6433
6434                         *des = 0xC0 | (t1 & 0x1F);
6435                         *(des+1) = 0x80 | (t2 & 0x3F);
6436
6437                         des += 2;
6438                         szSrc += 1;
6439                         nChar -= 1;
6440
6441                 } else {
6442                         return -1;
6443                 }
6444
6445         }
6446
6447 __RETURN:
6448         *des = 0;
6449         return(des - org);
6450 }
6451
6452 static int __MsgGetLatin72UTFCodeSize(unsigned char *szSrc, int nChar)
6453 {
6454         int nCount = 0;
6455
6456         MSG_DEBUG("MsgGetLatin72UTFCodeSize: --------------- \n");
6457
6458         if ((szSrc == NULL) || (nChar <= 0))
6459                 return 0;
6460
6461         while ((nChar > 0) && (*szSrc != '\0')) {
6462
6463                 if ((*szSrc >= 0x01 && *szSrc <= 0x7F) || (*szSrc == 0xA0)) {
6464                         nCount += 1;
6465                         szSrc++;
6466                         nChar--;
6467                 } else if (*szSrc == 0x00 || (0x80 <= *szSrc && *szSrc <= 0x9F) || (0xA3 <= *szSrc && *szSrc <= 0xAD) ||
6468                                         (0xB0 <= *szSrc && *szSrc <= 0xB4) || (0xB5 <= *szSrc && *szSrc <= 0xFE)) {
6469                         nCount += 2;
6470                         szSrc++;
6471                         nChar--;
6472                 } else if (*szSrc == 0xA1 ||*szSrc == 0xA2 || *szSrc == 0xAF) {
6473                         nCount += 3;
6474                         szSrc += 1;
6475                         nChar -= 1;
6476
6477                 } else {
6478                         return -1;
6479                 }
6480         }
6481         return nCount;
6482 }
6483
6484 static int __MsgUnicode2UTF(unsigned char *des, int outBufSize, unsigned short *szSrc, int nChar)
6485 {
6486         unsigned char *org;
6487         unsigned char t1;
6488         unsigned char t2;
6489         unsigned char t3;
6490
6491         MSG_DEBUG("MsgUnicode2UTF: --------------- \n");
6492
6493         org = des;
6494         outBufSize--;                   // NULL character
6495
6496         while ((nChar > 0) && (*szSrc != '\0')) {
6497                 if (0x0001 <= *szSrc && *szSrc <= 0x007F) {
6498                         /* check outbuffer's room for this UTF8 character */
6499
6500                         outBufSize --;
6501                         if (outBufSize < 0)
6502                                 goto __RETURN;
6503
6504                         *des = (unsigned char) (*szSrc & 0x007F);
6505
6506                         des++;
6507                         szSrc++;
6508                         nChar--;
6509                 } else if  ((*szSrc == 0x0000) || (0x0080 <= *szSrc && *szSrc <= 0x07FF)) {
6510                         /* check outbuffer's room for this UTF8 character */
6511
6512                         outBufSize -= 2;
6513                         if (outBufSize < 0)
6514                                 goto __RETURN;
6515
6516                         t2 = (unsigned char) (*szSrc & 0x003F);                         //      right most 6 bit
6517                         t1 = (unsigned char) ((*szSrc & 0x07C0) >> 6);          //      right most 5 bit
6518
6519                         *des = 0xC0 | (t1 & 0x1F);
6520                         *(des+1) = 0x80 | (t2 & 0x3F);
6521
6522                         des += 2;
6523                         szSrc += 1;
6524                         nChar -= 1;
6525                 } else {
6526                         /* check outbuffer's room for this UTF8 character */
6527
6528                         outBufSize -= 3;
6529                         if (outBufSize < 0)
6530                                 goto __RETURN;
6531
6532                         t3 = (unsigned char) (*szSrc & 0x003F);                                 //      right most 6 bit
6533                         t2 = (unsigned char) ((*szSrc & 0x0FC0) >> 6);                  //      right most 6 bit
6534                         t1 = (unsigned char) ((*szSrc & 0xF000) >> 12);                 //      right most 4 bit
6535
6536                         *des = 0xE0 | (t1 & 0x0F);
6537                         *(des+1) = 0x80 | (t2 & 0x3F);
6538                         *(des+2) = 0x80 | (t3 & 0x3F);
6539
6540                         des += 3;
6541                         szSrc += 1;
6542                         nChar -= 1;
6543                 }
6544         }
6545
6546 __RETURN:
6547
6548         *des = 0;
6549         return (des - org);
6550 }
6551
6552 static int __MsgGetUnicode2UTFCodeSize(unsigned short *szSrc, int nChar)
6553 {
6554         int nCount = 0;
6555
6556         MSG_DEBUG("MsgGetUnicode2UTFCodeSize: --------------- \n");
6557
6558         if ((szSrc == NULL) || (nChar <= 0)) {
6559                 MSG_DEBUG("MsgGetUnicode2UTFCodeSize: szSrc is NULL !!!! --------------- \n");
6560                 return 0;
6561         }
6562
6563         while ((nChar > 0) && (*szSrc != '\0')) {
6564                 if (0x0001 <= *szSrc && *szSrc <= 0x007F) {
6565                         nCount += 1;
6566                         szSrc++;
6567                         nChar--;
6568                 } else if  ((*szSrc == 0x0000) || (0x0080 <= *szSrc && *szSrc <= 0x07FF)) {
6569                         nCount += 2;
6570                         szSrc++;
6571                         nChar--;
6572                 } else {
6573                         nCount += 3;
6574                         szSrc++;
6575                         nChar--;
6576                 }
6577         }
6578
6579         return nCount;
6580 }
6581
6582 static bool __MmsAddrUtilCheckEmailAddress(char *pszAddr)
6583 {
6584         if (!pszAddr || pszAddr[0] == 0)
6585                 return false;
6586
6587         if (!strchr (pszAddr, MSG_MMS_CH_EMAIL_AT))
6588                 return false;
6589
6590         return true;
6591 }
6592
6593 bool MmsAddrUtilRemovePlmnString(char *pszAddr)
6594 {
6595         char *pszAddrCopy = NULL;
6596         char *pszStrStart = NULL;
6597         char *pszStrTemp = NULL;
6598         int strLen = 0;
6599
6600         if ((!pszAddr) || (pszAddr[0] == 0)) {
6601                 MSG_DEBUG("MmsAddrUtilRemovePlmnString: pszAddr is null or zero\n");
6602                 return false;
6603         }
6604
6605         strLen = strlen(pszAddr);
6606
6607         pszAddrCopy = (char*)calloc(1,strLen + 1);
6608         if (!pszAddrCopy) {
6609                 MSG_DEBUG("MmsAddrUtilRemovePlmnString: pszAddrCopy is NULL, mem alloc failed\n");
6610                 return false;
6611         }
6612
6613         strcpy(pszAddrCopy, pszAddr);
6614
6615
6616         pszAddr[0] = 0;
6617         pszStrStart = pszAddrCopy;
6618
6619         while (true) {
6620                 char*   pszStrEnd = NULL;
6621                 int             addressLen = 0;
6622
6623                 if (__MmsAddrUtilCheckEmailAddress(pszAddrCopy))
6624                         pszStrEnd = strstr(pszStrStart, "/TYPE=PLMN");
6625                 else
6626                         pszStrEnd = strstr(pszStrStart, "/");
6627
6628                 if (!pszStrEnd) {
6629                         // "/TYPE=PLMN" not found
6630
6631                         int remainedLen = strlen(pszStrStart);
6632
6633                         if (remainedLen <= 0)
6634                                 break;
6635
6636                         strcat(pszAddr, pszStrStart);
6637
6638                         break;
6639                 }
6640
6641                 // Get one address length
6642                 addressLen = pszStrEnd - pszStrStart;
6643
6644                 strncat(pszAddr, pszStrStart, addressLen);
6645
6646                 // Find next address
6647                 pszStrStart = pszStrEnd;
6648
6649                 pszStrTemp = strstr(pszStrStart, MSG_MMS_STR_ADDR_DELIMETER);
6650
6651                 if (pszStrTemp) {
6652                         addressLen = pszStrTemp - pszStrEnd;
6653                         pszStrStart += addressLen;
6654                 } else {
6655                         pszStrStart += strlen(pszStrEnd);
6656                 }
6657
6658                 if (pszStrStart[0] == 0)        // end of string
6659                         break;
6660
6661
6662                 strcat(pszAddr, MSG_MMS_STR_ADDR_DELIMETER);    // add ';'
6663                 pszStrStart++;  // remove ';'
6664         }
6665
6666         if (pszAddr[0] == 0)
6667                 strcpy(pszAddr, pszAddrCopy);
6668
6669         free(pszAddrCopy);
6670
6671         return true;
6672 }
6673
6674 static int __MsgCutUTFString(unsigned char *des, int outBufSize, unsigned char *szSrc, int nChar)
6675 {
6676         unsigned char *org;
6677
6678         MSG_DEBUG("MsgCutUTFString: --------------- \n");
6679
6680         org = des;
6681         outBufSize--;                   // NULL character
6682
6683         while ((nChar > 0) && (*szSrc != '\0')) {
6684                 if (*szSrc < 0x80) {
6685                         outBufSize --;
6686                         if (outBufSize < 0)
6687                                 goto __RETURN;
6688
6689                         *des = *szSrc;
6690                         des++;
6691                         szSrc++;
6692                 } else if  (((0xC0 <= *szSrc) && (*szSrc < 0xE0)) && (*(szSrc+1) >= 0x80)) {
6693                         outBufSize -= 2;
6694                         if (outBufSize < 0)
6695                                 goto __RETURN;
6696
6697                         *des = *szSrc;
6698                         *(des + 1) = *(szSrc + 1);
6699
6700                         des += 2;
6701                         szSrc += 2;
6702                 } else if  ((*szSrc >= 0xE0) && (*(szSrc+1) >= 0x80) && (*(szSrc+2) >= 0x80)) {
6703                         outBufSize -= 3;
6704                         if (outBufSize < 0)
6705                                 goto __RETURN;
6706
6707                         *des = *szSrc;
6708                         *(des + 1) = *(szSrc + 1);
6709                         *(des + 2) = *(szSrc + 2);
6710
6711                         des += 3;
6712                         szSrc += 3;
6713                 } else {
6714                         outBufSize --;
6715                         if (outBufSize < 0)
6716                                 goto __RETURN;
6717
6718                         *des = *szSrc;
6719                         des++;
6720                         szSrc++;
6721                         MSG_DEBUG("MsgCutUTFString: utf8 incorrect range!\n");
6722                 }
6723
6724                 nChar--;
6725         }
6726
6727 __RETURN:
6728
6729         *des = 0;
6730         return (des - org);
6731 }
6732
6733 static void __MsgMIMERemoveQuote(char *szSrc)
6734 {
6735         int             length = 0;
6736
6737         length = MsgStrlen(szSrc);
6738         if (szSrc[0] == MSG_CH_QUOT && szSrc[length-1] == MSG_CH_QUOT) {
6739                 int index = 0;
6740
6741                 for (index = 0; index < length-2; index++)
6742                         szSrc[index] = szSrc[index+1];
6743                 szSrc[index] = '\0';
6744         }
6745 }
6746
6747 static bool __MsgLoadDataToDecodeBuffer(FILE *pFile, char **ppBuf, int *pPtr, int *pOffset, char *pInBuf1, char *pInBuf2, int maxLen, int *pBufLen, int endOfFile)
6748 {
6749         MSG_BEGIN();
6750         int nRead = 0;
6751         int length= 0;
6752
6753         MSG_DEBUG("MsgLoadDataToDecodeBuffer: \n");
6754
6755         if (pFile == NULL) {
6756                 MSG_DEBUG("Error");
6757
6758                 *pBufLen = 0;
6759                 return false;
6760         }
6761
6762         if (pPtr == NULL || pInBuf1 == NULL || pInBuf2 == NULL) {
6763                 MSG_DEBUG("Error");
6764
6765                 *pBufLen = 0;
6766                 return false;
6767         }
6768
6769         if (*pBufLen == 0) {
6770                 length = maxLen - (*pPtr);
6771         } else {
6772                 length = (*pBufLen) - (*pPtr);
6773         }
6774
6775         if (length < 0)
6776                 length = 0;
6777
6778         if ((*ppBuf) == NULL) {
6779                 memset(pInBuf1, 0, maxLen);
6780                 (*ppBuf) = pInBuf1;
6781         } else if ((*ppBuf) == pInBuf1) {
6782                 memset(pInBuf2, 0, maxLen);
6783                 if (length)
6784                         memcpy(pInBuf2, pInBuf1 + (*pPtr), length);
6785                 (*ppBuf) = pInBuf2;
6786         } else {
6787                 memset(pInBuf1, 0, maxLen);
6788                 if (length)
6789                         memcpy(pInBuf1, pInBuf2 + (*pPtr), length);
6790                 (*ppBuf) = pInBuf1;
6791         }
6792
6793         (*pPtr) = 0;
6794
6795         if (*pOffset == endOfFile) {
6796                 *pBufLen = length;
6797                 return true;
6798         }
6799
6800         if (maxLen == length) {
6801                 /* (*pPtr) was 0 */
6802                 if (MsgReadFileForDecode(pFile, (*ppBuf), maxLen, &nRead) == false)
6803                         return false;
6804
6805                 *pBufLen = nRead;
6806         } else {
6807                 if (MsgReadFileForDecode(pFile, (*ppBuf) + length, maxLen - length, &nRead) == false)
6808                         return false;
6809
6810                 *pBufLen = length + nRead;
6811         }
6812
6813         if ((*pOffset = MsgFtell(pFile)) == -1L) {
6814                 MSG_DEBUG("MsgFtell Error");
6815                 return false;
6816         }
6817
6818         MSG_END();
6819
6820         return true;
6821 }
6822
6823
6824 bool MsgGetTypeByFileName(int *type, char *szFileName)
6825 {
6826         char *pExt   = NULL;
6827         AvCodecType AvType = AV_CODEC_NONE;
6828
6829         pExt = strrchr(szFileName, '.');
6830         if (pExt == NULL || pExt[0] == '\0')
6831                 goto __CATCH;
6832
6833         pExt++;
6834
6835         if (strcasecmp(pExt, "mp4") == 0 ||strcasecmp(pExt, "mpeg4") == 0 ||strcasecmp(pExt, "3gp") == 0 ||strcasecmp(pExt, "3gpp") == 0) {
6836
6837                 if (szFileName[0] != '/')
6838                         goto __CATCH;
6839
6840                 AvType = AvGetFileCodecType(szFileName);
6841                 MSG_DEBUG("MsgGetTypeByFileName:AvType(0x%x)\n", AvType);
6842
6843                 switch (AvType) {
6844                 case AV_DEC_AUDIO_MPEG4:
6845                         *type = MIME_AUDIO_MP4;
6846                         break;
6847
6848                 case AV_DEC_VIDEO_MPEG4:
6849                         *type = MIME_VIDEO_MP4;
6850                         break;
6851
6852                 default:
6853                         *type = MIME_VIDEO_3GPP;
6854                         break;
6855                 }
6856                 return true;
6857         }
6858
6859         if (strcasecmp(pExt, "amr") == 0) {
6860                 *type = MIME_AUDIO_AMR;
6861                 return true;
6862         } else if ((strcasecmp(pExt, "mid") == 0) || (strcasecmp(pExt, "midi") == 0)) {
6863                 *type = MIME_AUDIO_MIDI;
6864                 return true;
6865         } else if (strcasecmp(pExt, "imy") == 0) {
6866                 *type = MIME_TEXT_X_IMELODY;
6867                 return true;
6868         }
6869
6870         *type = MimeGetMimeFromExtInt((const char*)pExt);
6871         MSG_DEBUG("MsgGetTypeByFileName: szFileName = %s     type = %d \n", szFileName, type);
6872         return true;
6873
6874
6875 __CATCH:
6876
6877         *type = MIME_UNKNOWN;
6878         MSG_DEBUG("MsgGetTypeByFileName: szFileName = %s     type = %d \n", szFileName, type);
6879
6880         return false;
6881
6882 }
6883
6884
6885 /*
6886  *      This function write media data from raw data to file.
6887  *      @param  pMsg
6888  *      @param  pPartBody
6889  *      @param  pszMailboxPath  : path of mailbox
6890  *      @param  pszMsgFilename  : name of msg file
6891  *      @param  index                   : used for file naming
6892  *      @param  bSave                   : if true, file will be save otherwise just filename will be stored.
6893  */
6894 static bool __MmsMultipartSaveAsTempFile(MsgType *pPartType, MsgBody *pPartBody, char *pszMailboxPath, char *pszMsgFilename, int index, bool bSave)
6895 {
6896         FILE *pFile = NULL;
6897         char szFileName[MSG_FILENAME_LEN_MAX+1] = {0, };        // file name of temp file
6898         char szFullPath[MSG_FILEPATH_LEN_MAX] = {0, }; // full absolute path of temp file.
6899
6900         MSG_DEBUG("****   _MmsSaveMediaData:  [Multi part]  START  ***\n");
6901
6902         if (!pPartType) {
6903                 MSG_DEBUG("pPartType is NULL\n");
6904                 return false;
6905         }
6906
6907         if (pPartType->type == MIME_APPLICATION_SMIL) {
6908                 snprintf(szFileName, MSG_FILENAME_LEN_MAX+1, "%s", "smil.txt");
6909         } else {
6910                 if (pPartType->param.szName[0] != '\0') {
6911                         snprintf(szFileName, MSG_FILENAME_LEN_MAX+1, "%s", pPartType->param.szName);
6912                 } else if (pPartType->param.szFileName[0] != '\0') {
6913                         snprintf(szFileName, MSG_FILENAME_LEN_MAX+1, "%s", pPartType->param.szFileName);
6914                 } else {
6915                         snprintf(szFileName, MSG_FILENAME_LEN_MAX+1, "%lu", (unsigned long)index);
6916                 }
6917         }
6918
6919
6920 #ifndef __SUPPORT_DRM__
6921         __MsgMakeFileName(pPartType->type, szFileName, 0);      //FL & CD -> extension(.dm) SD -> extension(.dcf)
6922 #else
6923         __MsgMakeFileName(pPartType->type, szFileName, pPartType->drmInfo.drmType, 0);  //FL & CD -> extension(.dm) SD -> extension(.dcf)
6924         if (MsgDRMIsForwardLockType(pPartType->drmInfo.drmType))
6925                 MsgChangeDrm2FileName(szFileName);
6926 #endif
6927
6928
6929         snprintf(szFullPath, MSG_FILEPATH_LEN_MAX, "%s%s.dir/%s", pszMailboxPath, pszMsgFilename, szFileName);  // get absolute path of each temp file of each part
6930         snprintf(pPartType->param.szFileName, MSG_FILENAME_LEN_MAX+1, "%s.dir/%s", pszMsgFilename, szFileName);// store relative path of each temp file of each part including sub folder.
6931
6932         if (pPartType->param.szName[0]  == '\0') {
6933                 snprintf(pPartType->param.szName, MSG_LOCALE_FILENAME_LEN_MAX+1, "%s", szFileName);
6934                 MSG_DEBUG("Set Name : %s", pPartType->param.szName);
6935         }
6936
6937         if (pPartType->type == MIME_APPLICATION_OCTET_STREAM)
6938                 MsgGetTypeByFileName(&pPartType->type, szFullPath);
6939
6940         // save file
6941         if (bSave) {
6942                 if ((pFile = MsgOpenFile(szFullPath, "wb+")) == NULL) {
6943                         MSG_DEBUG("MsgOpenFile failed");
6944                         goto __CATCH;
6945                 }
6946
6947                 if (__MmsGetMediaPartData(pPartType, pPartBody, pFile) == false) {
6948                         MSG_DEBUG("MmsGetMediaPartData fail [index:%d]\n", index);
6949                         goto __CATCH;
6950                 }
6951
6952                 MsgCloseFile(pFile);
6953                 pFile = NULL;
6954
6955                 snprintf(pPartBody->szOrgFilePath, sizeof(pPartBody->szOrgFilePath), "%s", szFullPath);
6956                 pPartBody->offset = 0;
6957                 pPartBody->size = MsgGetFileSize(pPartBody->szOrgFilePath);
6958
6959                 MSG_DEBUG("Save Temp File to [%s]", pPartBody->szOrgFilePath);
6960
6961                 if (pPartType->drmInfo.drmType != MSG_DRM_TYPE_NONE) {
6962                         MsgDrmRegisterFile(MSG_MODE_FILE, szFullPath, strlen(szFullPath));
6963
6964                         /* change szDrm2FullPath as current content path*/
6965                         if (pPartType->drmInfo.szDrm2FullPath) {
6966                                 free(pPartType->drmInfo.szDrm2FullPath);
6967                                 pPartType->drmInfo.szDrm2FullPath = MsgStrCopy(szFullPath);
6968                         }
6969                 }
6970
6971         }
6972         MSG_DEBUG("****   MmsGetMediaPartData:  [Multi part]  E  N  D  (Successfully)  ***\n");
6973
6974         return true;
6975
6976 __CATCH:
6977
6978         if (pFile != NULL) {
6979                 MsgCloseFile(pFile);
6980                 pFile = NULL;
6981         }
6982
6983         return false;
6984 }
6985
6986 static bool __MmsGetMediaPartData(MsgType *pPartType, MsgBody *pPartBody, FILE* pFile)
6987 {
6988         int nRead = 0;
6989         int nRead2 = 0;
6990         char *pData = NULL;
6991         char *pNewData = NULL;
6992         char *pTempData = NULL;
6993         int msgEncodingValue = 0;
6994         int msgTypeValue = 0;
6995         int msgCharsetValue     = 0;
6996         int cidLen = 0;
6997         char *szCid = NULL;
6998         int offset = 0;
6999         int size = 0;
7000
7001         msgEncodingValue = pPartType->encoding;
7002         msgTypeValue = pPartType->type;
7003         msgCharsetValue = pPartType->param.charset;
7004
7005         cidLen = MsgStrlen(szCid);
7006
7007         offset = pPartBody->offset;
7008         size = pPartBody->size;
7009
7010         if (pPartBody->szOrgFilePath[0]) {
7011                 pTempData = MsgOpenAndReadMmsFile(pPartBody->szOrgFilePath, offset, size, &nRead);
7012
7013                 if (pTempData == NULL) {
7014                         MSG_DEBUG("MmsGetMediaPartData : pTempData read fail\n");
7015                         goto __CATCH;
7016                 }
7017
7018                 pData = pTempData;
7019         } else if (pPartBody->body.pText) {
7020                 pData = pPartBody->body.pText;
7021                 nRead = pPartBody->size;
7022         }
7023
7024         if (pData == NULL) {
7025                 MSG_DEBUG("MmsGetMediaPartData : there is no data \n");
7026                 goto __RETURN;
7027         }
7028
7029         pNewData = __MmsGetBinaryUTF8Data(pData, nRead, msgEncodingValue, msgTypeValue, msgCharsetValue, &nRead2);
7030         pPartType->encoding = MSG_ENCODING_BINARY;
7031
7032         if (__MsgIsText(msgTypeValue))
7033                 pPartType->param.charset = MSG_CHARSET_UTF8;
7034
7035         if (MsgWriteFile(pNewData, sizeof(char), nRead2,  pFile) != (size_t)nRead2) {
7036                 MSG_DEBUG("MmsGetMediaPartData: file writing fail \n");
7037
7038                 goto __CATCH;
7039         }
7040
7041 __RETURN:
7042
7043         if (pNewData) {
7044                 free(pNewData);
7045                 pNewData = NULL;
7046         }
7047
7048         if (pTempData) {
7049                 free(pTempData);
7050                 pTempData = NULL;
7051         }
7052
7053         return true;
7054
7055 __CATCH:
7056
7057         if (pNewData) {
7058                 free(pNewData);
7059                 pNewData = NULL;
7060         }
7061
7062         if (pTempData) {
7063                 free(pTempData);
7064                 pTempData = NULL;
7065         }
7066
7067         return false;
7068 }
7069
7070 static char *__MmsGetBinaryUTF8Data(char *pData, int nRead, int msgEncodingValue, int msgTypeValue, int msgCharsetValue, int *npRead)
7071 {
7072         int nChar = 0;
7073         int nByte = 0;
7074         int nTemp = 0;
7075         char *pTemp = NULL;
7076         unsigned short *mszTempStr = NULL;
7077         char *pConvertedStr     = NULL;
7078         char *pConvertedData = NULL;
7079         char *pNewData = NULL;
7080         char *pReturnData = NULL;
7081
7082
7083         switch (msgEncodingValue) {
7084         case MSG_ENCODING_BASE64:
7085
7086                 pConvertedData = (char*)MsgDecodeBase64((UCHAR*)pData, (ULONG)nRead, (ULONG*)&nByte);
7087                 MSG_DEBUG("MmsGetBinaryUTF8Data : MSG_ENCODING_BASE64     bodyLength = %d \n", nByte);
7088
7089                 pTemp = pConvertedData;
7090                 nTemp = nByte;
7091
7092                 break;
7093
7094         case MSG_ENCODING_QUOTE_PRINTABLE:
7095
7096                 pConvertedData = (char*)MsgDecodeQuotePrintable((UCHAR*)pData, (ULONG)nRead, (ULONG*)&nByte);
7097                 MSG_DEBUG("MmsGetBinaryUTF8Data: MSG_ENCODING_QUOTE_PRINTABLE     bodyLength = %d \n", nByte);
7098
7099                 pTemp = pConvertedData;
7100                 nTemp = nByte;
7101
7102                 break;
7103
7104         default:
7105
7106                 MSG_DEBUG("MmsGetBinaryUTF8Data: 8bit    OR    Binary   bodyLength = %d \n", nRead);
7107
7108                 pTemp = pData;
7109                 nTemp = nRead;
7110
7111                 break;
7112         }
7113
7114         if (__MsgIsText(msgTypeValue)) {
7115                 /* charset converting */
7116
7117                 switch (msgCharsetValue) {
7118                 case MSG_CHARSET_UTF16:
7119                 case MSG_CHARSET_USC2:
7120
7121                         MSG_DEBUG("MmsGetBinaryUTF8Data: MSG_CHARSET_USC2 \n");
7122
7123                         if (((UINT8)pTemp[0]) == 0xFF && ((UINT8)pTemp[1]) == 0xFE) {
7124                                 nChar = (nTemp / 2 - 1);
7125
7126                                 mszTempStr = (unsigned short*) malloc(nChar * sizeof(unsigned short));
7127                                 if (mszTempStr == NULL) {
7128                                         MSG_DEBUG("MmsGetBinaryUTF8Data : 1. Memory Full !!! \n");
7129                                         goto __CATCH;
7130                                 }
7131
7132                                 memcpy(mszTempStr, ((unsigned short*)pTemp + 1), nChar * sizeof(unsigned short));
7133
7134                                 nByte = __MsgGetUnicode2UTFCodeSize(((unsigned short*)pTemp + 1), nChar);
7135                                 if (nByte < 3)
7136                                         nByte = 3; //min value
7137
7138                                 pConvertedStr = (char *)malloc(nByte + 1);
7139                                 if (pConvertedStr != NULL)
7140                                         __MsgUnicode2UTF ((unsigned char*)pConvertedStr, nByte + 1, mszTempStr, nChar);
7141                         } else {
7142                                 nChar = (nTemp / 2);
7143
7144                                 mszTempStr = (unsigned short*) malloc(nChar * sizeof(unsigned short));
7145                                 if (mszTempStr == NULL) {
7146                                         MSG_DEBUG("MmsGetBinaryUTF8Data: 2. Memory Full !!! \n");
7147                                         goto __CATCH;
7148                                 }
7149
7150                                 memcpy(mszTempStr, ((unsigned short*)pTemp), nChar * sizeof(unsigned short));
7151
7152                                 nByte = __MsgGetUnicode2UTFCodeSize(((unsigned short*)pTemp), nChar);
7153
7154                                 pConvertedStr = (char *)malloc(nByte + 1);
7155                                 if (pConvertedStr)
7156                                         __MsgUnicode2UTF ((unsigned char*)pConvertedStr, nByte + 1, mszTempStr, nChar);
7157                         }
7158
7159                         if (pConvertedStr != NULL)
7160                                 pNewData = pConvertedStr;
7161
7162                         *npRead = nByte + 1;
7163
7164                         break;
7165
7166                 case MSG_CHARSET_US_ASCII:
7167
7168                         MSG_DEBUG("MmsGetBinaryUTF8Data: MSG_CHARSET_US_ASCII \n");
7169
7170                         /* fall through */
7171
7172                 case MSG_CHARSET_UTF8:
7173
7174                         MSG_DEBUG("MmsGetBinaryUTF8Data: MSG_CHARSET_UTF8 or Others \n");
7175
7176                         // skip BOM (Byte Order Mark) bytes .. (Please refer to the http://www.unicode.org/faq/utf_bom.html#BOM)
7177                         if (nTemp >= 3) {
7178                                 if (((UINT8)pTemp[0]) == 0xEF && ((UINT8)pTemp[1]) == 0xBB && ((UINT8)pTemp[2]) == 0xBF) {
7179                                         pTemp += 3;
7180                                         nTemp -= 3;
7181                                 }
7182                         }
7183                         pNewData = pTemp;
7184                         *npRead = nTemp;
7185
7186                         break;
7187
7188                 case MSG_CHARSET_ISO_8859_7:
7189
7190                         /* Greek */
7191
7192                         MSG_DEBUG("MmsGetBinaryUTF8Data: MSG_CHARSET_ISO_8859_7 \n");
7193
7194                         nByte = __MsgGetLatin72UTFCodeSize((unsigned char*)pTemp, nTemp);
7195                         pConvertedStr = (char *)malloc(nByte + 1);
7196                         if (pConvertedStr)
7197                                 __MsgLatin7code2UTF((unsigned char*)pConvertedStr, nByte + 1, (unsigned char*)pTemp, nTemp);
7198
7199                         pNewData = pConvertedStr;
7200                         *npRead = nByte + 1;
7201
7202                         break;
7203
7204                 case MSG_CHARSET_ISO_8859_9:
7205
7206                         /* Turkish */
7207                         MSG_DEBUG("MmsGetBinaryUTF8Data: MSG_CHARSET_ISO_8859_9 \n");
7208
7209                         nByte = __MsgGetLatin52UTFCodeSize((unsigned char*)pTemp, nTemp);
7210                         pConvertedStr = (char *)malloc(nByte + 1);
7211                         if (pConvertedStr)
7212                                         __MsgLatin5code2UTF((unsigned char*)pConvertedStr, nByte + 1, (unsigned char*)pTemp, nTemp);
7213
7214                         pNewData = pConvertedStr;
7215                         *npRead = nByte + 1;
7216
7217                         break;
7218
7219                 default:
7220
7221                         MSG_DEBUG("MmsGetBinaryUTF8Data: Other charsets \n");
7222
7223                         nByte = __MsgGetLatin2UTFCodeSize((unsigned char*)pTemp, nTemp);
7224                         pConvertedStr = (char *)malloc(nByte + 1);
7225                         if (pConvertedStr)
7226                                 __MsgLatin2UTF((unsigned char*)pConvertedStr, nByte + 1, (unsigned char*)pTemp, nTemp);
7227
7228                         pNewData = pConvertedStr;
7229                         *npRead = nByte + 1;
7230
7231                         break;
7232                 }
7233         } else {
7234                 pNewData = pTemp;
7235                 *npRead = nTemp;
7236         }
7237
7238         pReturnData = (char *)malloc(*npRead);
7239         if (pReturnData == NULL) {
7240                 MSG_DEBUG("MmsGetBinaryUTF8Data : pReturnData alloc fail. \n");
7241
7242                 goto __CATCH;
7243         }
7244
7245         if (pNewData != NULL) {
7246                 memset(pReturnData, 0, *npRead);
7247                 memcpy(pReturnData, pNewData, *npRead);
7248         }
7249
7250         if (pConvertedData) {
7251                 free(pConvertedData);
7252                 pConvertedData = NULL;
7253         }
7254
7255         if (pConvertedStr) {
7256                 free(pConvertedStr);
7257                 pConvertedStr = NULL;
7258         }
7259
7260         if (mszTempStr) {
7261                 free(mszTempStr);
7262                 mszTempStr = NULL;
7263         }
7264
7265         return pReturnData;
7266
7267 __CATCH:
7268
7269         if (pConvertedData) {
7270                 free(pConvertedData);
7271                 pConvertedData = NULL;
7272         }
7273
7274         if (pConvertedStr) {
7275                 free(pConvertedStr);
7276                 pConvertedStr = NULL;
7277         }
7278
7279         if (mszTempStr) {
7280                 free(mszTempStr);
7281                 mszTempStr = NULL;
7282         }
7283
7284         return NULL;
7285 }
7286
7287 #ifndef __SUPPORT_DRM__
7288 static bool __MsgMakeFileName(int iMsgType, char *szFileName, int nUntitleIndex)
7289 {
7290         char szText[MSG_FILENAME_LEN_MAX+1]={0,};
7291         char szTemp[MSG_FILENAME_LEN_MAX+1]={0,};
7292         char szTempFileName[MSG_FILENAME_LEN_MAX+1]={0,};
7293         char *pExt = NULL;
7294
7295
7296         MSG_DEBUG("MsgMakeFileName: iMsgType = %d     szFileName = %s \n", iMsgType, szFileName);
7297
7298         if (szFileName == NULL)
7299                 return false;
7300
7301         if (szFileName && (szFileName[0] != '\0')) {
7302                 MsgGetFileNameWithoutExtension (szTempFileName, szFileName);
7303
7304                 pExt = strrchr(szTempFileName, '.');
7305                 if (pExt == NULL) {
7306                         memset  (szText, 0, MSG_FILENAME_LEN_MAX+1);
7307                         strncpy(szText, szTempFileName, MSG_FILEPATH_LEN_MAX - 1);
7308                         strcat(szText, ".");                    // add '.'
7309                 } else {
7310                         memset  (szText, 0, MSG_FILENAME_LEN_MAX+1);
7311                         strncpy(szText, szTempFileName, pExt+1 - szFileName);   // add '.'
7312                 }
7313         } else {
7314                 if (nUntitleIndex >= 1) {
7315                         snprintf(szText, MSG_FILENAME_LEN_MAX+1, "%s_%d.", "Untitled", nUntitleIndex);
7316                 } else {
7317                         snprintf(szText, MSG_FILENAME_LEN_MAX+1, "%s.", "Untitled");
7318                 }
7319         }
7320
7321         if (iMsgType == MIME_APPLICATION_OCTET_STREAM) {
7322                 MSG_DEBUG("MsgMakeFileName: unsupported MsgType\n");
7323                 goto __CATCH;
7324         } else {
7325                 int             nLen = 0;
7326                 strncpy(szTemp, szText, MSG_FILENAME_LEN_MAX - 5);
7327                 if (iMsgType == MIME_UNKNOWN || (pExt = MimeGetExtFromMimeInt((MimeType)iMsgType)) == NULL) {
7328                         MSG_DEBUG("MsgMakeFileName: Failed to get extension of that mime data file. \n");
7329                         goto __CATCH;
7330                 }
7331                 nLen = MSG_FILENAME_LEN_MAX - strlen(szTemp);
7332                 strncat(szTemp, pExt, nLen);
7333         }
7334
7335
7336         strcpy(szFileName, szTemp);
7337
7338         MSG_DEBUG("MsgMakeFileName: made szFileName = %s \n", szFileName);
7339
7340         return true;
7341
7342 __CATCH:
7343         {
7344                 char *p = NULL;
7345                 p = strrchr(szText, '.');
7346                 if (p != NULL)
7347                         *p = 0;
7348                 snprintf(szFileName, MSG_FILENAME_LEN_MAX+1, "%s", szText);
7349
7350                 return false;
7351         }
7352 }
7353 #else
7354 static bool __MsgMakeFileName(int iMsgType, char *szFileName, MsgDrmType drmType, int nUntitleIndex)
7355 {
7356         char szText[MSG_FILENAME_LEN_MAX+1]={0,};
7357         char szTemp[MSG_FILENAME_LEN_MAX+1]={0,};
7358         char szTempFileName[MSG_FILENAME_LEN_MAX+1]={0,};
7359         char *pExt = NULL;
7360
7361         MSG_DEBUG("MsgMakeFileName: iMsgType = 0x%x, drmType = %d, szFileName = %s \n", iMsgType, drmType, szFileName);
7362
7363         if (szFileName == NULL)
7364                 return false;
7365
7366         if (szFileName && (szFileName[0] != '\0')) {
7367                 MsgGetFileNameWithoutExtension (szTempFileName, szFileName);
7368
7369                 if (drmType != MSG_DRM_TYPE_NONE) {
7370                         pExt = strrchr(szTempFileName, '.');
7371                         if (pExt == NULL) {
7372                                 memset(szText, 0, MSG_FILENAME_LEN_MAX+1);
7373                                 strncpy(szText, szTempFileName, MSG_FILENAME_LEN_MAX - 1);
7374                                 strcat(szText, ".");                    // add '.'
7375                         } else {
7376                                 memset(szText, 0, MSG_FILENAME_LEN_MAX+1);
7377                                 strncpy(szText, szTempFileName, pExt+1 - szFileName);
7378                         }
7379                 } else {
7380                         pExt = strrchr(szTempFileName, '.');
7381                         if (pExt == NULL) {
7382                                 memset(szText, 0, MSG_FILENAME_LEN_MAX+1);
7383                                 strncpy(szText, szTempFileName, MSG_FILENAME_LEN_MAX - 1);
7384                                 strcat(szText, ".");
7385                         } else  {
7386                                 return true;
7387                         }
7388                 }
7389         } else {
7390                 if (nUntitleIndex >= 1) {
7391                         snprintf(szText, MSG_FILENAME_LEN_MAX+1, "%s_%d.", "untitled", nUntitleIndex);
7392                 } else {
7393                         snprintf(szText, MSG_FILENAME_LEN_MAX+1, "%s.", "untitled");
7394                 }
7395         }
7396
7397         if (drmType == MSG_DRM_TYPE_SD) {
7398                 strncpy(szTemp, szText, MSG_FILENAME_LEN_MAX - 5);
7399                 strcat(szTemp, "dcf");
7400         } else if (MsgDRMIsForwardLockType(drmType)) {
7401                 strncpy(szTemp, szText, MSG_FILENAME_LEN_MAX - 4);
7402                 strcat(szTemp, "dm");
7403         } else {
7404                 if (iMsgType == MIME_APPLICATION_OCTET_STREAM) {
7405                         MSG_DEBUG("MsgMakeFileName: unsupported MsgType\n");
7406                         goto __CATCH;
7407                 } else {
7408                         int             nLen = 0;
7409                         strncpy(szTemp, szText, MSG_FILENAME_LEN_MAX - 5);
7410                         //temporary commented to save file as original name.
7411                         if (pExt == NULL) {
7412
7413                                 if (iMsgType == MIME_UNKNOWN || (pExt = MimeGetExtFromMimeInt((MimeType)iMsgType)) == NULL) {
7414                                         MSG_DEBUG("MsgMakeFileName: Failed to get extension of that mime data file. \n");
7415                                         goto __CATCH;
7416                                 }
7417                         }
7418
7419                         nLen = MSG_FILENAME_LEN_MAX - strlen(szTemp);
7420                         strncat(szTemp, pExt, nLen);
7421                 }
7422         }
7423
7424         strcpy(szFileName, szTemp);
7425
7426         MSG_DEBUG("MsgMakeFileName: made szFileName = %s \n", szFileName);
7427
7428         return true;
7429
7430 __CATCH:
7431         {
7432                 char *p = NULL;
7433                 p = strrchr(szText, '.');
7434                 if (p != NULL)
7435                         *p = 0;
7436                 snprintf(szFileName, MSG_FILENAME_LEN_MAX+1, "%s", szText);
7437
7438                 return false;
7439         }
7440 }
7441 #endif
7442
7443 bool MsgGetFileNameWithoutExtension (char *szOutputName, char *szName)
7444 {
7445         char *pszExt = NULL;
7446
7447         if (szOutputName == NULL) {
7448                 MSG_DEBUG("szOutputName is NULL");
7449                 return false;
7450         }
7451
7452         strncpy(szOutputName, szName, strlen(szName));
7453
7454         if ((pszExt = strrchr(szOutputName, '.'))) {
7455                 if (pszExt[0] == '.')
7456                         pszExt[0] = '\0';
7457         }
7458
7459         return true;
7460 }
7461
7462 int MmsGetMediaPartCount(msg_message_id_t msgId)
7463 {
7464         MmsMsg *pMsg;
7465
7466         MmsPluginStorage::instance()->getMmsMessage(&pMsg);
7467
7468         if (msgId != pMsg->msgID) {
7469                 MSG_DEBUG("Invalid Message Id");
7470                 return -1;
7471         }
7472
7473         return pMsg->nPartCount;
7474 }
7475
7476 bool MmsGetMediaPartHeader(int index, MsgType *pHeader)
7477 {
7478         MmsMsg *pMsg = NULL;
7479         MsgMultipart *pPart = NULL;
7480
7481         if (pHeader == NULL) {
7482                 MSG_DEBUG("MmsGetMediaPartHeader: Invalid pHeader input. It's null \n");
7483                 return false;
7484         }
7485
7486         MmsPluginStorage::instance()->getMmsMessage(&pMsg);
7487
7488         MmsInitMsgType(pHeader);
7489
7490
7491         /* Requires header of non-presentation */
7492         if (MsgIsMultipart(pMsg->msgType.type)) {
7493                 MSG_DEBUG("MmsGetMediaPartHeader: Multipart header [index = %d] \n", index);
7494
7495                 pPart = pMsg->msgBody.body.pMultipart;
7496
7497                 while (pPart && index--)
7498                         pPart = pPart->pNext;
7499
7500                 if (pPart == NULL) {
7501                         MSG_DEBUG("MmsGetMediaPartHeader: There is no such msg part.\n");
7502                         return false;
7503                 }
7504
7505                 memcpy(pHeader, &pPart->type, sizeof(MsgType));
7506         } else {
7507                 MSG_DEBUG("MmsGetMediaPartHeader: Requires singlepart header \n");
7508                 memcpy(pHeader, &pMsg->msgType, sizeof(MsgType));
7509         }
7510
7511         return true;
7512 }
7513
7514 static bool __MmsDebugPrintMulitpartEntry(MsgMultipart *pMultipart, int index)
7515 {
7516         MSG_DEBUG("------------------------------\n");
7517         MSG_DEBUG("%dth multipart info\n", index);
7518         MSG_DEBUG("header size=%d\n", pMultipart->type.size);
7519         MSG_DEBUG("body size=%d\n", pMultipart->type.contentSize);
7520         MSG_DEBUG("content type=%s\n", MmsDebugGetMimeType((MimeType)pMultipart->type.type));
7521         MSG_DEBUG("content ID=%s\n", pMultipart->type.szContentID);
7522         MSG_DEBUG("content location=%s\n", pMultipart->type.szContentLocation);
7523
7524         if (pMultipart->type.type == MIME_TEXT_PLAIN) {
7525                 MSG_DEBUG("text info\n");
7526                 MSG_DEBUG("charset=%d\n", pMultipart->type.param.charset);
7527                 MSG_DEBUG("text file name=%s\n", pMultipart->type.param.szName);
7528         }
7529 #ifdef __SUPPORT_DRM__
7530         if (pMultipart->type.drmInfo.drmType != MSG_DRM_TYPE_NONE) {
7531                 MSG_DEBUG("drm info\n");
7532                 MSG_DEBUG("drm type=%d      (0: NONE 1: Fowward Lock, 2:Combined Delivery, 3: Separated Delivery)\n", pMultipart->type.drmInfo.drmType);
7533                 MSG_DEBUG("drm content type=%s\n", MmsDebugGetMimeType((MimeType)pMultipart->type.drmInfo.contentType));
7534                 MSG_DEBUG("drm content URI=%s\n", pMultipart->type.drmInfo.szContentURI);
7535                 MSG_DEBUG("drm2FullPath=%s\n", pMultipart->type.drmInfo.szDrm2FullPath);
7536         }
7537 #endif
7538         MSG_DEBUG("------------------------------\n");
7539         return true;
7540 }