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