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