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